grit_pattern_matcher/pattern/
iter_pattern.rs

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// todo maybe add variable?
48#[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(&not.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}