grit_pattern_matcher/pattern/
or.rs

1use super::{
2    ast_node_pattern::AstNodePattern,
3    functions::{Evaluator, FuncEvaluation},
4    patterns::{Matcher, Pattern, PatternName},
5    predicates::Predicate,
6    resolved_pattern::ResolvedPattern,
7    State,
8};
9use crate::{binding::Binding, context::QueryContext};
10use core::fmt::Debug;
11use grit_util::{error::GritResult, AnalysisLogs};
12
13#[derive(Debug, Clone)]
14pub struct Or<Q: QueryContext> {
15    pub patterns: Vec<Pattern<Q>>,
16}
17
18impl<Q: QueryContext> Or<Q> {
19    pub fn new(patterns: Vec<Pattern<Q>>) -> Self {
20        Self { patterns }
21    }
22}
23
24impl<Q: QueryContext> PatternName for Or<Q> {
25    fn name(&self) -> &'static str {
26        "OR"
27    }
28}
29
30impl<Q: QueryContext> Matcher<Q> for Or<Q> {
31    fn execute<'a>(
32        &'a self,
33        resolved: &Q::ResolvedPattern<'a>,
34        init_state: &mut State<'a, Q>,
35        context: &'a Q::ExecContext<'a>,
36        logs: &mut AnalysisLogs,
37    ) -> GritResult<bool> {
38        if let Some(binding) = resolved.get_last_binding() {
39            for p in self.patterns.iter() {
40                // filter out pattern which cannot match because of a mismatched node type
41                if let (Some(binding_node), Pattern::AstNode(node_pattern)) = (binding.as_node(), p)
42                {
43                    if !node_pattern.matches_kind_of(&binding_node) {
44                        continue;
45                    }
46                }
47                let mut state = init_state.clone();
48                let res = p.execute(resolved, &mut state, context, logs)?;
49                if res {
50                    *init_state = state;
51                    return Ok(true);
52                }
53            }
54        } else {
55            for p in self.patterns.iter() {
56                let mut state = init_state.clone();
57                let res = p.execute(resolved, &mut state, context, logs)?;
58                if res {
59                    *init_state = state;
60                    return Ok(true);
61                }
62            }
63        };
64        Ok(false)
65    }
66}
67
68#[derive(Debug, Clone)]
69pub struct PrOr<Q: QueryContext> {
70    pub predicates: Vec<Predicate<Q>>,
71}
72
73impl<Q: QueryContext> PrOr<Q> {
74    pub fn new(predicates: Vec<Predicate<Q>>) -> Self {
75        Self { predicates }
76    }
77}
78
79impl<Q: QueryContext> PatternName for PrOr<Q> {
80    fn name(&self) -> &'static str {
81        "PREDICATE_OR"
82    }
83}
84
85impl<Q: QueryContext> Evaluator<Q> for PrOr<Q> {
86    fn execute_func<'a>(
87        &'a self,
88        init_state: &mut State<'a, Q>,
89        context: &'a Q::ExecContext<'a>,
90        logs: &mut AnalysisLogs,
91    ) -> GritResult<FuncEvaluation<Q>> {
92        for p in self.predicates.iter() {
93            let mut state = init_state.clone();
94            let res = p.execute_func(&mut state, context, logs)?;
95            if res.predicator || res.ret_val.is_some() {
96                *init_state = state;
97                return Ok(res);
98            }
99        }
100        Ok(FuncEvaluation {
101            predicator: false,
102            ret_val: None,
103        })
104    }
105}