grit_pattern_matcher/
context.rs1use crate::{
2 binding::Binding,
3 file_owners::FileOwners,
4 pattern::{
5 AstLeafNodePattern, AstNodePattern, CallBuiltIn, CallbackPattern, CodeSnippet, File,
6 GritFunctionDefinition, Pattern, PatternDefinition, PredicateDefinition, ResolvedPattern,
7 State,
8 },
9};
10use grit_util::{error::GritResult, AnalysisLogs, Ast, AstNode, Language};
11
12pub trait QueryContext: Clone + std::fmt::Debug + Sized + 'static {
14 type Node<'a>: AstNode + Clone;
15 type NodePattern: AstNodePattern<Self>;
16 type LeafNodePattern: AstLeafNodePattern<Self>;
17 type ExecContext<'a>: ExecContext<'a, Self>;
18 type Binding<'a>: Binding<'a, Self>;
19 type CodeSnippet: CodeSnippet<Self>;
20 type ResolvedPattern<'a>: ResolvedPattern<'a, Self>;
21 type Language<'a>: Language<Node<'a> = Self::Node<'a>>;
22 type File<'a>: File<'a, Self>;
23 type Tree<'a>: Ast<Node<'a> = Self::Node<'a>> + Clone;
24}
25
26pub trait ExecContext<'a, Q: QueryContext> {
28 fn pattern_definitions(&self) -> &[PatternDefinition<Q>];
29
30 fn predicate_definitions(&self) -> &[PredicateDefinition<Q>];
31
32 fn function_definitions(&self) -> &[GritFunctionDefinition<Q>];
33
34 fn ignore_limit_pattern(&self) -> bool;
35
36 fn call_built_in(
37 &self,
38 call: &'a CallBuiltIn<Q>,
39 context: &'a Self,
40 state: &mut State<'a, Q>,
41 logs: &mut AnalysisLogs,
42 ) -> GritResult<Q::ResolvedPattern<'a>>;
43
44 fn call_callback<'b>(
45 &self,
46 call: &'a CallbackPattern,
47 context: &'a Self,
48 binding: &'b Q::ResolvedPattern<'a>,
49 state: &mut State<'a, Q>,
50 logs: &mut AnalysisLogs,
51 ) -> GritResult<bool>;
52
53 fn load_file(
58 &self,
59 file: &Q::File<'a>,
60 state: &mut State<'a, Q>,
61 logs: &mut AnalysisLogs,
62 ) -> GritResult<bool>;
63
64 fn files(&self) -> &FileOwners<Q::Tree<'a>>;
66
67 fn language(&self) -> &Q::Language<'a>;
68
69 fn exec_step(
70 &'a self,
71 step: &'a Pattern<Q>,
72 binding: &Q::ResolvedPattern<'a>,
73 state: &mut State<'a, Q>,
74 logs: &mut AnalysisLogs,
75 ) -> GritResult<bool>;
76
77 fn name(&self) -> Option<&str>;
78}
79
80#[derive(Debug)]
83pub struct StaticDefinitions<'a, Q: QueryContext> {
84 pattern_definitions: &'a [PatternDefinition<Q>],
85 predicate_definitions: &'a [PredicateDefinition<Q>],
86 function_definitions: &'a [GritFunctionDefinition<Q>],
87 pub skippable_indexes: Vec<usize>,
89}
90
91impl<'a, Q: QueryContext> StaticDefinitions<'a, Q> {
92 pub fn new(
93 pattern_definitions: &'a [PatternDefinition<Q>],
94 predicate_definitions: &'a [PredicateDefinition<Q>],
95 function_definitions: &'a [GritFunctionDefinition<Q>],
96 ) -> Self {
97 StaticDefinitions {
98 pattern_definitions,
99 predicate_definitions,
100 function_definitions,
101 skippable_indexes: vec![],
102 }
103 }
104
105 pub fn get_pattern(&self, index: usize) -> Option<&PatternDefinition<Q>> {
106 if self.skippable_indexes.contains(&index) {
107 return None;
108 }
109 self.pattern_definitions.get(index)
110 }
111
112 pub fn get_predicate(&self, index: usize) -> Option<&PredicateDefinition<Q>> {
113 self.predicate_definitions.get(index)
114 }
115
116 pub fn get_function(&self, index: usize) -> Option<&GritFunctionDefinition<Q>> {
117 self.function_definitions.get(index)
118 }
119}
120
121impl<'a, Q: QueryContext> Default for StaticDefinitions<'a, Q> {
122 fn default() -> Self {
123 Self {
124 pattern_definitions: &[],
125 predicate_definitions: &[],
126 function_definitions: &[],
127 skippable_indexes: vec![],
128 }
129 }
130}