fork of https://github.com/tree-sitter/tree-sitter-graph

Factor out strict query match visit

Changed files
+54 -45
src
execution
+4 -6
src/execution/lazy.rs
··· 187 187 trace!("{{"); 188 188 for statement in &self.statements { 189 189 let error_context = { 190 - let node = mat 191 - .captures 192 - .iter() 193 - .find(|c| c.index as usize == self.full_match_file_capture_index) 194 - .expect("missing capture for full match") 195 - .node; 190 + let node = self 191 + .full_capture_from_file_match(mat) 192 + .next() 193 + .expect("missing capture for full match"); 196 194 StatementContext::new(&statement, &self, &node) 197 195 }; 198 196 let mut exec = ExecutionContext {
+50 -39
src/execution/strict.rs
··· 86 86 let mut scoped = ScopedVariables::new(); 87 87 let current_regex_captures = Vec::new(); 88 88 let mut function_parameters = Vec::new(); 89 - let mut cursor = QueryCursor::new(); 90 - for stanza in &self.stanzas { 91 - cancellation_flag.check("executing stanza")?; 89 + 90 + self.try_visit_matches_strict(tree, source, |stanza, mat| { 92 91 stanza.execute( 93 - tree, 94 92 source, 93 + &mat, 95 94 graph, 96 95 &mut config, 97 96 &mut locals, 98 97 &mut scoped, 99 98 &current_regex_captures, 100 99 &mut function_parameters, 101 - &mut cursor, 102 100 &self.shorthands, 103 101 cancellation_flag, 104 - )?; 102 + ) 103 + })?; 104 + 105 + Ok(()) 106 + } 107 + 108 + pub(super) fn try_visit_matches_strict<'a, 'tree, E, F>( 109 + &self, 110 + tree: &'tree Tree, 111 + source: &'tree str, 112 + mut visit: F, 113 + ) -> Result<(), E> 114 + where 115 + F: FnMut(&Stanza, QueryMatch<'_, 'tree>) -> Result<(), E>, 116 + { 117 + let mut cursor = QueryCursor::new(); 118 + for stanza in &self.stanzas { 119 + let matches = cursor.matches(&stanza.query, tree.root_node(), source.as_bytes()); 120 + for mat in matches { 121 + visit(stanza, mat)?; 122 + } 105 123 } 106 124 Ok(()) 107 125 } ··· 141 159 impl Stanza { 142 160 fn execute<'a, 'g, 'l, 's, 'tree>( 143 161 &self, 144 - tree: &'tree Tree, 145 162 source: &'tree str, 163 + mat: &QueryMatch<'_, 'tree>, 146 164 graph: &mut Graph<'tree>, 147 165 config: &ExecutionConfig<'_, 'g>, 148 166 locals: &mut VariableMap<'l, Value>, 149 167 scoped: &mut ScopedVariables<'s>, 150 168 current_regex_captures: &Vec<String>, 151 169 function_parameters: &mut Vec<Value>, 152 - cursor: &mut QueryCursor, 153 170 shorthands: &AttributeShorthands, 154 171 cancellation_flag: &dyn CancellationFlag, 155 172 ) -> Result<(), ExecutionError> { 156 - let matches = cursor.matches(&self.query, tree.root_node(), source.as_bytes()); 157 - for mat in matches { 158 - cancellation_flag.check("processing matches")?; 159 - locals.clear(); 160 - for statement in &self.statements { 161 - let error_context = { 162 - let node = mat 163 - .captures 164 - .iter() 165 - .find(|c| c.index as usize == self.full_match_stanza_capture_index) 166 - .expect("missing capture for full match") 167 - .node; 168 - StatementContext::new(&statement, &self, &node) 169 - }; 170 - let mut exec = ExecutionContext { 171 - source, 172 - graph, 173 - config, 174 - locals, 175 - scoped, 176 - current_regex_captures, 177 - function_parameters, 178 - mat: &mat, 179 - error_context, 180 - shorthands, 181 - cancellation_flag, 182 - }; 183 - statement 184 - .execute(&mut exec) 185 - .with_context(|| exec.error_context.into())?; 186 - } 173 + locals.clear(); 174 + for statement in &self.statements { 175 + let error_context = { 176 + let node = self 177 + .full_capture_from_stanza_match(mat) 178 + .next() 179 + .expect("missing capture for full match"); 180 + StatementContext::new(&statement, &self, &node) 181 + }; 182 + let mut exec = ExecutionContext { 183 + source, 184 + graph, 185 + config, 186 + locals, 187 + scoped, 188 + current_regex_captures, 189 + function_parameters, 190 + mat: &mat, 191 + error_context, 192 + shorthands, 193 + cancellation_flag, 194 + }; 195 + statement 196 + .execute(&mut exec) 197 + .with_context(|| exec.error_context.into())?; 187 198 } 188 199 Ok(()) 189 200 }