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