grit_pattern_matcher/pattern/
before.rs1use super::{
2 patterns::{Matcher, Pattern, PatternName},
3 resolved_pattern::ResolvedPattern,
4 State,
5};
6use crate::{
7 binding::Binding,
8 context::{ExecContext, QueryContext},
9 errors::debug,
10};
11use grit_util::{
12 error::{GritPatternError, GritResult},
13 AnalysisLogs, AstNode,
14};
15
16#[derive(Debug, Clone)]
17pub struct Before<Q: QueryContext> {
18 pub before: Pattern<Q>,
19}
20
21impl<Q: QueryContext> Before<Q> {
22 pub fn new(before: Pattern<Q>) -> Self {
23 Self { before }
24 }
25
26 pub fn prev_pattern<'a>(
27 &'a self,
28 state: &mut State<'a, Q>,
29 context: &'a Q::ExecContext<'a>,
30 logs: &mut AnalysisLogs,
31 ) -> GritResult<Q::ResolvedPattern<'a>> {
32 let binding = Q::Binding::from_pattern(&self.before, state, context, logs)?;
33 let Some(node) = binding.as_node() else {
34 return Err(GritPatternError::new(
35 "cannot get the node before this binding",
36 ));
37 };
38
39 if let Some(prev) = node.previous_named_node() {
40 Ok(ResolvedPattern::from_node_binding(prev))
41 } else {
42 debug(
43 logs,
44 state,
45 context.language(),
46 "no node before current node, treating as undefined",
47 )?;
48 Ok(Q::ResolvedPattern::undefined())
49 }
50 }
51}
52
53impl<Q: QueryContext> PatternName for Before<Q> {
54 fn name(&self) -> &'static str {
55 "BEFORE"
56 }
57}
58
59impl<Q: QueryContext> Matcher<Q> for Before<Q> {
60 fn execute<'a>(
61 &'a self,
62 binding: &Q::ResolvedPattern<'a>,
63 init_state: &mut State<'a, Q>,
64 context: &'a Q::ExecContext<'a>,
65 logs: &mut AnalysisLogs,
66 ) -> GritResult<bool> {
67 let Some(binding) = binding.get_last_binding() else {
68 return Ok(true);
69 };
70 let mut cur_state = init_state.clone();
71 let Some(node) = binding.as_node() else {
73 return Ok(true);
74 };
75 let Some(next_node) = node.next_named_node() else {
76 return Ok(false);
77 };
78 if !self.before.execute(
79 &ResolvedPattern::from_node_binding(next_node),
80 &mut cur_state,
81 context,
82 logs,
83 )? {
84 return Ok(false);
85 }
86 *init_state = cur_state;
87 Ok(true)
88 }
89}