1use super::{
2 accessor::Accessor, container::Container, dynamic_snippet::DynamicPattern,
3 list_index::ListIndex, patterns::Pattern, predicates::Predicate, regex::RegexLike,
4};
5use crate::{
6 context::{QueryContext, StaticDefinitions},
7 pattern::{
8 ast_node_pattern::AstNodePattern,
9 list_index::{ContainerOrIndex, ListOrContainer},
10 patterns::CodeSnippet,
11 },
12};
13
14pub struct PatternOrPredicateIterator<'a, Q: QueryContext> {
15 patterns: Vec<PatternOrPredicate<'a, Q>>,
16 definitions: &'a StaticDefinitions<'a, Q>,
17}
18
19impl<'a, Q: QueryContext> Iterator for PatternOrPredicateIterator<'a, Q> {
20 type Item = PatternOrPredicate<'a, Q>;
21
22 fn next(&mut self) -> Option<Self::Item> {
23 if let Some(pattern) = self.patterns.pop() {
24 self.patterns.extend(pattern.children(self.definitions));
25 Some(pattern)
26 } else {
27 None
28 }
29 }
30}
31
32impl<'a, Q: QueryContext> PatternOrPredicateIterator<'a, Q> {
33 fn from_pattern(pattern: &'a Pattern<Q>, definitions: &'a StaticDefinitions<Q>) -> Self {
34 Self {
35 patterns: vec![PatternOrPredicate::Pattern(pattern)],
36 definitions,
37 }
38 }
39 fn from_predicate(predicate: &'a Predicate<Q>, definitions: &'a StaticDefinitions<Q>) -> Self {
40 Self {
41 patterns: vec![PatternOrPredicate::Predicate(predicate)],
42 definitions,
43 }
44 }
45}
46
47#[derive(Clone, Copy)]
49pub enum PatternOrPredicate<'a, Q: QueryContext> {
50 Pattern(&'a Pattern<Q>),
51 Predicate(&'a Predicate<Q>),
52 DynamicPattern(&'a DynamicPattern<Q>),
53}
54
55impl<'a, Q: QueryContext> PatternOrPredicate<'a, Q> {
56 fn children(&self, definitions: &'a StaticDefinitions<Q>) -> Vec<PatternOrPredicate<'a, Q>> {
57 match self {
58 PatternOrPredicate::Pattern(p) => p.children(definitions),
59 PatternOrPredicate::Predicate(p) => p.children(definitions),
60 PatternOrPredicate::DynamicPattern(p) => p.children(definitions),
61 }
62 }
63}
64
65impl<Q: QueryContext> Predicate<Q> {
66 pub fn iter<'a>(
67 &'a self,
68 definitions: &'a StaticDefinitions<Q>,
69 ) -> PatternOrPredicateIterator<'a, Q> {
70 PatternOrPredicateIterator::from_predicate(self, definitions)
71 }
72
73 fn children<'a>(
74 &'a self,
75 definitions: &'a StaticDefinitions<Q>,
76 ) -> Vec<PatternOrPredicate<'a, Q>> {
77 match self {
78 Predicate::Call(call) => {
79 let mut base = args_children(&call.args, definitions);
80 let def = definitions.get_predicate(call.index);
81 if let Some(def) = def {
82 base.push(PatternOrPredicate::Predicate(&def.predicate));
83 }
84 base
85 }
86 Predicate::CallBuiltIn(call_built_in) => {
87 let mut base = args_children(&call_built_in.args, definitions);
88 let def = definitions.get_predicate(call_built_in.index);
89 if let Some(def) = def {
90 base.push(PatternOrPredicate::Predicate(&def.predicate));
91 }
92 base
93 }
94 Predicate::Not(not) => vec![PatternOrPredicate::Predicate(¬.predicate)],
95 Predicate::If(if_) => vec![
96 PatternOrPredicate::Predicate(&if_.if_),
97 PatternOrPredicate::Predicate(&if_.then),
98 PatternOrPredicate::Predicate(&if_.else_),
99 ],
100 Predicate::True => vec![],
101 Predicate::False => vec![],
102 Predicate::Or(or) => predicates_children(&or.predicates, definitions),
103 Predicate::Maybe(m) => vec![PatternOrPredicate::Predicate(&m.predicate)],
104 Predicate::And(and) => predicates_children(&and.predicates, definitions),
105 Predicate::Any(any) => predicates_children(&any.predicates, definitions),
106 Predicate::Rewrite(rewrite) => {
107 let mut res = rewrite.right.children(definitions);
108 res.push(PatternOrPredicate::Pattern(&rewrite.left));
109 res
110 }
111 Predicate::Match(match_) => match_
112 .pattern
113 .iter()
114 .map(PatternOrPredicate::Pattern)
115 .collect(),
116 Predicate::Equal(equal) => vec![PatternOrPredicate::Pattern(&equal.pattern)],
117 Predicate::Assignment(assignment) => {
118 vec![PatternOrPredicate::Pattern(&assignment.pattern)]
119 }
120 Predicate::Accumulate(accumulate) => vec![
121 PatternOrPredicate::Pattern(&accumulate.left),
122 PatternOrPredicate::Pattern(&accumulate.right),
123 ],
124 Predicate::Return(return_) => vec![PatternOrPredicate::Pattern(&return_.pattern)],
125 }
126 }
127}
128
129impl<Q: QueryContext> Container<Q> {
130 fn children<'a>(
131 &'a self,
132 definitions: &'a StaticDefinitions<Q>,
133 ) -> Vec<PatternOrPredicate<'a, Q>> {
134 match self {
135 Container::Variable(_) => vec![],
136 Container::Accessor(a) => a.children(definitions),
137 Container::ListIndex(l) => l.children(definitions),
138 Container::FunctionCall(f) => {
139 let mut base = args_children(&f.args, definitions);
140 let def = definitions.get_function(f.index);
141 if let Some(def) = def {
142 base.push(PatternOrPredicate::Predicate(&def.function));
143 }
144 base
145 }
146 }
147 }
148}
149
150impl<Q: QueryContext> Accessor<Q> {
151 fn children<'a>(
152 &'a self,
153 definitions: &'a StaticDefinitions<Q>,
154 ) -> Vec<PatternOrPredicate<'a, Q>> {
155 match &self.map {
156 super::accessor::AccessorMap::Container(c) => c.children(definitions),
157 super::accessor::AccessorMap::Map(m) => m
158 .elements
159 .values()
160 .map(PatternOrPredicate::Pattern)
161 .collect(),
162 }
163 }
164}
165
166impl<Q: QueryContext> DynamicPattern<Q> {
167 fn children<'a>(
168 &'a self,
169 definitions: &'a StaticDefinitions<Q>,
170 ) -> Vec<PatternOrPredicate<'a, Q>> {
171 match &self {
172 super::dynamic_snippet::DynamicPattern::Variable(_) => Vec::new(),
173 super::dynamic_snippet::DynamicPattern::Accessor(a) => a.children(definitions),
174 super::dynamic_snippet::DynamicPattern::ListIndex(l) => l.children(definitions),
175 super::dynamic_snippet::DynamicPattern::Snippet(_) => Vec::new(),
176 super::dynamic_snippet::DynamicPattern::List(l) => l
177 .elements
178 .iter()
179 .flat_map(|d| d.children(definitions))
180 .collect(),
181 super::dynamic_snippet::DynamicPattern::CallBuiltIn(c) => {
182 args_children(&c.args, definitions)
183 }
184 super::dynamic_snippet::DynamicPattern::CallFunction(c) => {
185 args_children(&c.args, definitions)
186 }
187 super::dynamic_snippet::DynamicPattern::CallForeignFunction(c) => {
188 args_children(&c.args, definitions)
189 }
190 }
191 }
192}
193
194impl<Q: QueryContext> ListIndex<Q> {
195 fn children<'a>(
196 &'a self,
197 definitions: &'a StaticDefinitions<Q>,
198 ) -> Vec<PatternOrPredicate<'a, Q>> {
199 let mut v = Vec::new();
200 let list = match &self.list {
201 ListOrContainer::Container(c) => c.children(definitions),
202 ListOrContainer::List(l) => patterns_children(&l.patterns, definitions),
203 };
204 let index = match &self.index {
205 ContainerOrIndex::Container(c) => c.children(definitions),
206 ContainerOrIndex::Index(_) => Vec::new(),
207 };
208 v.extend(list);
209 v.extend(index);
210 v
211 }
212}
213
214fn args_children<'a, Q: QueryContext>(
215 args: &'a [Option<Pattern<Q>>],
216 _definitions: &'a StaticDefinitions<Q>,
217) -> Vec<PatternOrPredicate<'a, Q>> {
218 args.iter()
219 .flat_map(|p| p.as_ref().map(PatternOrPredicate::Pattern))
220 .collect()
221}
222
223fn patterns_children<'a, Q: QueryContext>(
224 patterns: &'a [Pattern<Q>],
225 _definitions: &'a StaticDefinitions<Q>,
226) -> Vec<PatternOrPredicate<'a, Q>> {
227 patterns.iter().map(PatternOrPredicate::Pattern).collect()
228}
229
230fn predicates_children<'a, Q: QueryContext>(
231 predicates: &'a [Predicate<Q>],
232 _definitions: &'a StaticDefinitions<Q>,
233) -> Vec<PatternOrPredicate<'a, Q>> {
234 predicates
235 .iter()
236 .map(PatternOrPredicate::Predicate)
237 .collect()
238}
239
240impl<Q: QueryContext> Pattern<Q> {
241 pub fn iter<'a>(
242 &'a self,
243 definitions: &'a StaticDefinitions<Q>,
244 ) -> PatternOrPredicateIterator<'a, Q> {
245 PatternOrPredicateIterator::from_pattern(self, definitions)
246 }
247
248 fn children<'a>(
249 &'a self,
250 definitions: &'a StaticDefinitions<Q>,
251 ) -> Vec<PatternOrPredicate<'a, Q>> {
252 match self {
253 Pattern::AstNode(a) => a.children(definitions),
254 Pattern::List(l) => patterns_children(&l.patterns, definitions),
255 Pattern::ListIndex(l) => l.children(definitions),
256 Pattern::Map(m) => m
257 .elements
258 .values()
259 .map(PatternOrPredicate::Pattern)
260 .collect(),
261 Pattern::Accessor(a) => a.children(definitions),
262 Pattern::Call(c) => {
263 let mut base = args_children(&c.args, definitions);
264 let def = definitions.get_pattern(c.index);
265 if let Some(def) = def {
266 base.push(PatternOrPredicate::Pattern(def.pattern()));
267 }
268 base
269 }
270 Pattern::Regex(r) => {
271 if let RegexLike::Pattern(p) = &r.regex {
272 p.children(definitions)
273 } else {
274 Vec::new()
275 }
276 }
277 Pattern::File(f) => {
278 let mut v = Vec::new();
279 let n = f.name.children(definitions);
280 let b = f.body.children(definitions);
281 v.extend(n);
282 v.extend(b);
283 v
284 }
285 Pattern::Files(f) => f.pattern.children(definitions),
286 Pattern::Bubble(b) => {
287 let mut children = args_children(&b.args, definitions);
288 children.extend(b.pattern_def.pattern().children(definitions));
289 children
290 }
291 Pattern::Limit(l) => l.pattern.children(definitions),
292 Pattern::CallBuiltIn(c) => args_children(&c.args, definitions),
293 Pattern::CallFunction(c) => {
294 let mut children = args_children(&c.args, definitions);
295 let def = definitions.get_function(c.index);
296 if let Some(def) = def {
297 children.extend(def.function.children(definitions));
298 }
299 children
300 }
301 Pattern::CallForeignFunction(c) => args_children(&c.args, definitions),
302 Pattern::CallbackPattern(_) => vec![],
303 Pattern::Assignment(a) => vec![PatternOrPredicate::Pattern(&a.pattern)],
304 Pattern::Accumulate(a) => vec![
305 PatternOrPredicate::Pattern(&a.left),
306 PatternOrPredicate::Pattern(&a.right),
307 ],
308 Pattern::And(a) => patterns_children(&a.patterns, definitions),
309 Pattern::Or(o) => patterns_children(&o.patterns, definitions),
310 Pattern::Maybe(m) => vec![PatternOrPredicate::Pattern(&m.pattern)],
311 Pattern::Any(a) => patterns_children(&a.patterns, definitions),
312 Pattern::Not(n) => vec![PatternOrPredicate::Pattern(&n.pattern)],
313 Pattern::If(i) => vec![
314 PatternOrPredicate::Predicate(&i.if_),
315 PatternOrPredicate::Pattern(&i.then),
316 PatternOrPredicate::Pattern(&i.else_),
317 ],
318 Pattern::Undefined => Vec::new(),
319 Pattern::Top => Vec::new(),
320 Pattern::Bottom => Vec::new(),
321 Pattern::Underscore => Vec::new(),
322 Pattern::StringConstant(_) => Vec::new(),
323 Pattern::AstLeafNode(_) => Vec::new(),
324 Pattern::IntConstant(_) => Vec::new(),
325 Pattern::FloatConstant(_) => Vec::new(),
326 Pattern::BooleanConstant(_) => Vec::new(),
327 Pattern::Dynamic(d) => d.children(definitions),
328 Pattern::CodeSnippet(c) => {
329 let mut v = Vec::new();
330 let p = c.patterns().map(|p| PatternOrPredicate::Pattern(p));
331 let d = c
332 .dynamic_snippet()
333 .map(|d| d.children(definitions))
334 .unwrap_or(Vec::new());
335 v.extend(p);
336 v.extend(d);
337 v
338 }
339 Pattern::Variable(_) => Vec::new(),
340 Pattern::Rewrite(r) => {
341 vec![
342 PatternOrPredicate::Pattern(&r.left),
343 PatternOrPredicate::DynamicPattern(&r.right),
344 ]
345 }
346 Pattern::Range(_) => Vec::new(),
347 Pattern::Contains(c) => c
348 .until
349 .iter()
350 .map(PatternOrPredicate::Pattern)
351 .chain(Some(PatternOrPredicate::Pattern(&c.contains)))
352 .collect(),
353 Pattern::Includes(i) => vec![PatternOrPredicate::Pattern(&i.includes)],
354 Pattern::Within(w) => vec![PatternOrPredicate::Pattern(&w.pattern)],
355 Pattern::After(a) => vec![PatternOrPredicate::Pattern(&a.after)],
356 Pattern::Before(b) => vec![PatternOrPredicate::Pattern(&b.before)],
357 Pattern::Where(w) => vec![
358 PatternOrPredicate::Pattern(&w.pattern),
359 PatternOrPredicate::Predicate(&w.side_condition),
360 ],
361 Pattern::Some(s) => vec![PatternOrPredicate::Pattern(&s.pattern)],
362 Pattern::Every(a) => vec![PatternOrPredicate::Pattern(&a.pattern)],
363 Pattern::Add(a) => vec![
364 PatternOrPredicate::Pattern(&a.lhs),
365 PatternOrPredicate::Pattern(&a.rhs),
366 ],
367 Pattern::Subtract(a) => vec![
368 PatternOrPredicate::Pattern(&a.lhs),
369 PatternOrPredicate::Pattern(&a.rhs),
370 ],
371 Pattern::Multiply(a) => vec![
372 PatternOrPredicate::Pattern(&a.lhs),
373 PatternOrPredicate::Pattern(&a.rhs),
374 ],
375 Pattern::Divide(a) => vec![
376 PatternOrPredicate::Pattern(&a.lhs),
377 PatternOrPredicate::Pattern(&a.rhs),
378 ],
379 Pattern::Modulo(a) => vec![
380 PatternOrPredicate::Pattern(&a.lhs),
381 PatternOrPredicate::Pattern(&a.rhs),
382 ],
383 Pattern::Dots => Vec::new(),
384 Pattern::Sequential(s) => s
385 .iter()
386 .map(|s| PatternOrPredicate::Pattern(&s.pattern))
387 .collect(),
388 Pattern::Like(l) => vec![
389 PatternOrPredicate::Pattern(&l.like),
390 PatternOrPredicate::Pattern(&l.threshold),
391 ],
392 }
393 }
394}