mirror of
https://github.com/tree-sitter/tree-sitter.git
synced 2026-09-09 23:26:20 -04:00
fix(rust)!: expose QueryMatch::captures as a method
The field handed out a slice whose lifetime outlived the streaming-iterator loan it came from. An accessor reborrowing through `&self` bounds it correctly. BREAKING CHANGE: In the rust bindings, replace `m.captures` with `m.captures()`.
This commit is contained in:
parent
efa0dd9a36
commit
5ddf71b9f4
|
|
@ -75,7 +75,7 @@ pub fn query_file_at_path(
|
|||
if opts.ordered_captures {
|
||||
let mut captures = query_cursor.captures(&query, tree.root_node(), source_code.as_slice());
|
||||
while let Some((mat, capture_index)) = captures.next() {
|
||||
let capture = mat.captures[*capture_index];
|
||||
let capture = mat.captures()[*capture_index];
|
||||
let capture_name = &query.capture_names()[capture.index as usize];
|
||||
if !opts.quiet && !should_test {
|
||||
writeln!(
|
||||
|
|
@ -102,7 +102,7 @@ pub fn query_file_at_path(
|
|||
if !opts.quiet && !should_test {
|
||||
writeln!(&mut stdout, " pattern: {}", m.pattern_index)?;
|
||||
}
|
||||
for capture in m.captures {
|
||||
for capture in m.captures() {
|
||||
let start = capture.node.start_position();
|
||||
let end = capture.node.end_position();
|
||||
let capture_name = &query.capture_names()[capture.index as usize];
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ pub fn collect_matches<'a>(
|
|||
while let Some(m) = matches.next() {
|
||||
result.push((
|
||||
m.pattern_index,
|
||||
format_captures(m.captures.iter().into_streaming_iter_ref(), query, source),
|
||||
format_captures(m.captures().iter().into_streaming_iter_ref(), query, source),
|
||||
));
|
||||
}
|
||||
result
|
||||
|
|
@ -347,7 +347,7 @@ pub fn collect_captures<'a>(
|
|||
query: &'a Query,
|
||||
source: &'a str,
|
||||
) -> Vec<(&'a str, &'a str)> {
|
||||
format_captures(captures.map(|(m, i)| m.captures[*i]), query, source)
|
||||
format_captures(captures.map(|(m, i)| m.captures()[*i]), query, source)
|
||||
}
|
||||
|
||||
fn format_captures<'a>(
|
||||
|
|
|
|||
|
|
@ -2918,7 +2918,7 @@ fn test_query_matches_with_wildcard_at_root_intersecting_byte_range() {
|
|||
);
|
||||
|
||||
while let Some(mat) = match_iter.next() {
|
||||
if let Some(capture) = mat.captures.first() {
|
||||
if let Some(capture) = mat.captures().first() {
|
||||
matches.push(capture.node.kind());
|
||||
}
|
||||
}
|
||||
|
|
@ -2934,7 +2934,7 @@ fn test_query_matches_with_wildcard_at_root_intersecting_byte_range() {
|
|||
);
|
||||
|
||||
while let Some(mat) = match_iter.next() {
|
||||
if let Some(capture) = mat.captures.first() {
|
||||
if let Some(capture) = mat.captures().first() {
|
||||
matches.push(capture.node.kind());
|
||||
}
|
||||
}
|
||||
|
|
@ -2950,7 +2950,7 @@ fn test_query_matches_with_wildcard_at_root_intersecting_byte_range() {
|
|||
);
|
||||
|
||||
while let Some(mat) = match_iter.next() {
|
||||
if let Some(capture) = mat.captures.first() {
|
||||
if let Some(capture) = mat.captures().first() {
|
||||
matches.push(capture.node.kind());
|
||||
}
|
||||
}
|
||||
|
|
@ -3008,7 +3008,7 @@ fn test_query_captures_within_byte_range_assigned_after_iterating() {
|
|||
let mut results = Vec::new();
|
||||
let mut first_five = captures.by_ref().take(5);
|
||||
while let Some((mat, capture_ix)) = first_five.next() {
|
||||
let capture = mat.captures[*capture_ix];
|
||||
let capture = mat.captures()[*capture_ix];
|
||||
results.push((
|
||||
query.capture_names()[capture.index as usize],
|
||||
&source[capture.node.byte_range()],
|
||||
|
|
@ -3031,7 +3031,7 @@ fn test_query_captures_within_byte_range_assigned_after_iterating() {
|
|||
results.clear();
|
||||
captures.set_byte_range(source.find("Ok").unwrap()..source.len());
|
||||
while let Some((mat, capture_ix)) = captures.next() {
|
||||
let capture = mat.captures[*capture_ix];
|
||||
let capture = mat.captures()[*capture_ix];
|
||||
results.push((
|
||||
query.capture_names()[capture.index as usize],
|
||||
&source[capture.node.byte_range()],
|
||||
|
|
@ -3330,7 +3330,7 @@ fn test_query_matches_with_captured_wildcard_at_root() {
|
|||
|
||||
while let Some(m) = match_iter.next() {
|
||||
let captures = m
|
||||
.captures
|
||||
.captures()
|
||||
.iter()
|
||||
.map(|c| {
|
||||
(
|
||||
|
|
@ -4311,7 +4311,7 @@ fn test_query_captures_with_matches_removed() {
|
|||
|
||||
let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
|
||||
while let Some((m, i)) = captures.next() {
|
||||
let capture = m.captures[*i];
|
||||
let capture = m.captures()[*i];
|
||||
let text = capture.node.utf8_text(source.as_bytes()).unwrap();
|
||||
if text == "a" {
|
||||
m.remove();
|
||||
|
|
@ -4356,7 +4356,7 @@ fn test_query_captures_with_matches_removed_before_they_finish() {
|
|||
let mut captured_strings = Vec::new();
|
||||
let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
|
||||
while let Some((m, i)) = captures.next() {
|
||||
let capture = m.captures[*i];
|
||||
let capture = m.captures()[*i];
|
||||
let text = capture.node.utf8_text(source.as_bytes()).unwrap();
|
||||
if text == "as" {
|
||||
m.remove();
|
||||
|
|
@ -4397,18 +4397,18 @@ fn test_query_captures_and_matches_iterators_are_fused() {
|
|||
let mut cursor = QueryCursor::new();
|
||||
let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
|
||||
|
||||
assert_eq!(captures.next().unwrap().0.captures[0].index, 0);
|
||||
assert_eq!(captures.next().unwrap().0.captures[0].index, 0);
|
||||
assert_eq!(captures.next().unwrap().0.captures[0].index, 0);
|
||||
assert_eq!(captures.next().unwrap().0.captures()[0].index, 0);
|
||||
assert_eq!(captures.next().unwrap().0.captures()[0].index, 0);
|
||||
assert_eq!(captures.next().unwrap().0.captures()[0].index, 0);
|
||||
assert!(captures.next().is_none());
|
||||
assert!(captures.next().is_none());
|
||||
assert!(captures.next().is_none());
|
||||
drop(captures);
|
||||
|
||||
let mut matches = cursor.matches(&query, tree.root_node(), source.as_bytes());
|
||||
assert_eq!(matches.next().unwrap().captures[0].index, 0);
|
||||
assert_eq!(matches.next().unwrap().captures[0].index, 0);
|
||||
assert_eq!(matches.next().unwrap().captures[0].index, 0);
|
||||
assert_eq!(matches.next().unwrap().captures()[0].index, 0);
|
||||
assert_eq!(matches.next().unwrap().captures()[0].index, 0);
|
||||
assert_eq!(matches.next().unwrap().captures()[0].index, 0);
|
||||
assert!(matches.next().is_none());
|
||||
assert!(matches.next().is_none());
|
||||
assert!(matches.next().is_none());
|
||||
|
|
@ -4588,7 +4588,7 @@ fn test_query_lifetime_is_separate_from_nodes_lifetime() {
|
|||
.matches(&query, node, source.as_bytes())
|
||||
.next()
|
||||
.unwrap()
|
||||
.captures[0]
|
||||
.captures()[0]
|
||||
.node
|
||||
}
|
||||
|
||||
|
|
@ -4609,7 +4609,7 @@ fn test_query_lifetime_is_separate_from_nodes_lifetime() {
|
|||
.next()
|
||||
.unwrap()
|
||||
.0
|
||||
.captures[0]
|
||||
.captures()[0]
|
||||
.node
|
||||
}
|
||||
|
||||
|
|
@ -4819,7 +4819,7 @@ fn test_query_random() {
|
|||
let transformed_match = Match {
|
||||
last_node: None,
|
||||
captures: mat
|
||||
.captures
|
||||
.captures()
|
||||
.iter()
|
||||
.map(|c| (query.capture_names()[c.index as usize], c.node))
|
||||
.collect::<Vec<_>>(),
|
||||
|
|
@ -5833,10 +5833,10 @@ fn test_consecutive_zero_or_modifiers() {
|
|||
let mut len_1 = false;
|
||||
|
||||
while let Some(m) = matches.next() {
|
||||
if m.captures.len() == 3 {
|
||||
if m.captures().len() == 3 {
|
||||
len_3 = true;
|
||||
}
|
||||
if m.captures.len() == 1 {
|
||||
if m.captures().len() == 1 {
|
||||
len_1 = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -5898,7 +5898,7 @@ fn test_query_max_start_depth_more() {
|
|||
let query = Query::new(&language, "(compound_statement) @capture").unwrap();
|
||||
|
||||
let mut matches = cursor.matches(&query, tree.root_node(), source.as_bytes());
|
||||
let node = matches.next().unwrap().captures[0].node;
|
||||
let node = matches.next().unwrap().captures()[0].node;
|
||||
assert_eq!(node.kind(), "compound_statement");
|
||||
|
||||
for row in rows {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ fn tree_query<I: AsRef<[u8]>>(tree: &Tree, text: impl TextProvider<I>, language:
|
|||
let mut cursor = QueryCursor::new();
|
||||
let mut captures = cursor.captures(&query, tree.root_node(), text);
|
||||
let (match_, idx) = captures.next().unwrap();
|
||||
let capture = match_.captures[*idx];
|
||||
let capture = match_.captures()[*idx];
|
||||
assert_eq!(capture.index as usize, *idx);
|
||||
assert_eq!("comment", capture.node.kind());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -800,7 +800,7 @@ impl<'a> HighlightIterLayer<'a> {
|
|||
let next_start = self
|
||||
.captures
|
||||
.peek()
|
||||
.map(|(m, i)| m.captures[*i].node.start_byte());
|
||||
.map(|(m, i)| m.captures()[*i].node.start_byte());
|
||||
let next_end = self.highlight_end_stack.last().copied();
|
||||
match (next_start, next_end) {
|
||||
(Some(start), Some(end)) => {
|
||||
|
|
@ -926,7 +926,7 @@ where
|
|||
let range;
|
||||
let layer = &mut self.layers[0];
|
||||
if let Some((next_match, capture_index)) = layer.captures.peek() {
|
||||
let next_capture = next_match.captures[*capture_index];
|
||||
let next_capture = next_match.captures()[*capture_index];
|
||||
range = next_capture.node.byte_range();
|
||||
|
||||
// If any previous highlight ends before this node starts, then before
|
||||
|
|
@ -950,7 +950,7 @@ where
|
|||
}
|
||||
|
||||
let (mut match_, capture_index) = layer.captures.next().unwrap();
|
||||
let mut capture = match_.captures[capture_index];
|
||||
let mut capture = match_.captures()[capture_index];
|
||||
|
||||
// If this capture represents an injection, then process the injection.
|
||||
if match_.pattern_index < layer.config.locals_pattern_index {
|
||||
|
|
@ -1037,7 +1037,7 @@ where
|
|||
let scope = layer.scope_stack.last_mut().unwrap();
|
||||
|
||||
let mut value_range = 0..0;
|
||||
for capture in match_.captures {
|
||||
for capture in match_.captures() {
|
||||
if Some(capture.index) == layer.config.local_def_value_capture_index {
|
||||
value_range = capture.node.byte_range();
|
||||
}
|
||||
|
|
@ -1080,7 +1080,7 @@ where
|
|||
|
||||
// Continue processing any additional matches for the same node.
|
||||
if let Some((next_match, next_capture_index)) = layer.captures.peek() {
|
||||
let next_capture = next_match.captures[*next_capture_index];
|
||||
let next_capture = next_match.captures()[*next_capture_index];
|
||||
if next_capture.node == capture.node {
|
||||
capture = next_capture;
|
||||
match_ = layer.captures.next().unwrap().0;
|
||||
|
|
@ -1110,7 +1110,7 @@ where
|
|||
// captures are guaranteed to be for highlighting, not injections or
|
||||
// local variables.
|
||||
while let Some((next_match, next_capture_index)) = layer.captures.peek() {
|
||||
let next_capture = next_match.captures[*next_capture_index];
|
||||
let next_capture = next_match.captures()[*next_capture_index];
|
||||
if next_capture.node == capture.node {
|
||||
let following_match = layer.captures.next().unwrap().0;
|
||||
// If the current node was found to be a local variable, then ignore
|
||||
|
|
@ -1323,7 +1323,7 @@ fn injection_for_match<'a>(
|
|||
let mut language_name = None;
|
||||
let mut content_node = None;
|
||||
|
||||
for capture in query_match.captures {
|
||||
for capture in query_match.captures() {
|
||||
let index = Some(capture.index);
|
||||
if index == language_capture_index {
|
||||
language_name = capture.node.utf8_text(source).ok();
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ where
|
|||
let pattern_info = &self.config.pattern_info[mat.pattern_index];
|
||||
|
||||
if mat.pattern_index < self.config.tags_pattern_index {
|
||||
for capture in mat.captures {
|
||||
for capture in mat.captures() {
|
||||
let index = Some(capture.index);
|
||||
let range = capture.node.byte_range();
|
||||
if index == self.config.local_scope_capture_index {
|
||||
|
|
@ -405,7 +405,7 @@ where
|
|||
let mut docs_adjacent_node = None;
|
||||
let mut is_ignored = false;
|
||||
|
||||
for capture in mat.captures {
|
||||
for capture in mat.captures() {
|
||||
let index = Some(capture.index);
|
||||
|
||||
if index == self.config.ignore_capture_index {
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ pub struct QueryPredicate {
|
|||
/// A match of a [`Query`] to a particular set of [`Node`]s.
|
||||
pub struct QueryMatch<'cursor, 'tree> {
|
||||
pub pattern_index: usize,
|
||||
pub captures: &'cursor [QueryCapture<'tree>],
|
||||
captures: &'cursor [QueryCapture<'tree>],
|
||||
id: u32,
|
||||
cursor: *mut ffi::TSQueryCursor,
|
||||
}
|
||||
|
|
@ -3434,6 +3434,11 @@ impl<'tree> QueryMatch<'_, 'tree> {
|
|||
self.id
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn captures(&self) -> &[QueryCapture<'tree>] {
|
||||
self.captures
|
||||
}
|
||||
|
||||
#[doc(alias = "ts_query_cursor_remove_match")]
|
||||
pub fn remove(&self) {
|
||||
unsafe { ffi::ts_query_cursor_remove_match(self.cursor, self.id) }
|
||||
|
|
|
|||
Loading…
Reference in a new issue