mirror of
https://github.com/tree-sitter/tree-sitter.git
synced 2026-09-10 07:26:23 -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 {
|
if opts.ordered_captures {
|
||||||
let mut captures = query_cursor.captures(&query, tree.root_node(), source_code.as_slice());
|
let mut captures = query_cursor.captures(&query, tree.root_node(), source_code.as_slice());
|
||||||
while let Some((mat, capture_index)) = captures.next() {
|
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];
|
let capture_name = &query.capture_names()[capture.index as usize];
|
||||||
if !opts.quiet && !should_test {
|
if !opts.quiet && !should_test {
|
||||||
writeln!(
|
writeln!(
|
||||||
|
|
@ -102,7 +102,7 @@ pub fn query_file_at_path(
|
||||||
if !opts.quiet && !should_test {
|
if !opts.quiet && !should_test {
|
||||||
writeln!(&mut stdout, " pattern: {}", m.pattern_index)?;
|
writeln!(&mut stdout, " pattern: {}", m.pattern_index)?;
|
||||||
}
|
}
|
||||||
for capture in m.captures {
|
for capture in m.captures() {
|
||||||
let start = capture.node.start_position();
|
let start = capture.node.start_position();
|
||||||
let end = capture.node.end_position();
|
let end = capture.node.end_position();
|
||||||
let capture_name = &query.capture_names()[capture.index as usize];
|
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() {
|
while let Some(m) = matches.next() {
|
||||||
result.push((
|
result.push((
|
||||||
m.pattern_index,
|
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
|
result
|
||||||
|
|
@ -347,7 +347,7 @@ pub fn collect_captures<'a>(
|
||||||
query: &'a Query,
|
query: &'a Query,
|
||||||
source: &'a str,
|
source: &'a str,
|
||||||
) -> Vec<(&'a str, &'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>(
|
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() {
|
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());
|
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() {
|
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());
|
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() {
|
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());
|
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 results = Vec::new();
|
||||||
let mut first_five = captures.by_ref().take(5);
|
let mut first_five = captures.by_ref().take(5);
|
||||||
while let Some((mat, capture_ix)) = first_five.next() {
|
while let Some((mat, capture_ix)) = first_five.next() {
|
||||||
let capture = mat.captures[*capture_ix];
|
let capture = mat.captures()[*capture_ix];
|
||||||
results.push((
|
results.push((
|
||||||
query.capture_names()[capture.index as usize],
|
query.capture_names()[capture.index as usize],
|
||||||
&source[capture.node.byte_range()],
|
&source[capture.node.byte_range()],
|
||||||
|
|
@ -3031,7 +3031,7 @@ fn test_query_captures_within_byte_range_assigned_after_iterating() {
|
||||||
results.clear();
|
results.clear();
|
||||||
captures.set_byte_range(source.find("Ok").unwrap()..source.len());
|
captures.set_byte_range(source.find("Ok").unwrap()..source.len());
|
||||||
while let Some((mat, capture_ix)) = captures.next() {
|
while let Some((mat, capture_ix)) = captures.next() {
|
||||||
let capture = mat.captures[*capture_ix];
|
let capture = mat.captures()[*capture_ix];
|
||||||
results.push((
|
results.push((
|
||||||
query.capture_names()[capture.index as usize],
|
query.capture_names()[capture.index as usize],
|
||||||
&source[capture.node.byte_range()],
|
&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() {
|
while let Some(m) = match_iter.next() {
|
||||||
let captures = m
|
let captures = m
|
||||||
.captures
|
.captures()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| {
|
.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());
|
let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
|
||||||
while let Some((m, i)) = captures.next() {
|
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();
|
let text = capture.node.utf8_text(source.as_bytes()).unwrap();
|
||||||
if text == "a" {
|
if text == "a" {
|
||||||
m.remove();
|
m.remove();
|
||||||
|
|
@ -4356,7 +4356,7 @@ fn test_query_captures_with_matches_removed_before_they_finish() {
|
||||||
let mut captured_strings = Vec::new();
|
let mut captured_strings = Vec::new();
|
||||||
let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
|
let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
|
||||||
while let Some((m, i)) = captures.next() {
|
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();
|
let text = capture.node.utf8_text(source.as_bytes()).unwrap();
|
||||||
if text == "as" {
|
if text == "as" {
|
||||||
m.remove();
|
m.remove();
|
||||||
|
|
@ -4397,18 +4397,18 @@ fn test_query_captures_and_matches_iterators_are_fused() {
|
||||||
let mut cursor = QueryCursor::new();
|
let mut cursor = QueryCursor::new();
|
||||||
let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
|
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());
|
assert!(captures.next().is_none());
|
||||||
assert!(captures.next().is_none());
|
assert!(captures.next().is_none());
|
||||||
drop(captures);
|
drop(captures);
|
||||||
|
|
||||||
let mut matches = cursor.matches(&query, tree.root_node(), source.as_bytes());
|
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());
|
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())
|
.matches(&query, node, source.as_bytes())
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.captures[0]
|
.captures()[0]
|
||||||
.node
|
.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4609,7 +4609,7 @@ fn test_query_lifetime_is_separate_from_nodes_lifetime() {
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.0
|
||||||
.captures[0]
|
.captures()[0]
|
||||||
.node
|
.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4819,7 +4819,7 @@ fn test_query_random() {
|
||||||
let transformed_match = Match {
|
let transformed_match = Match {
|
||||||
last_node: None,
|
last_node: None,
|
||||||
captures: mat
|
captures: mat
|
||||||
.captures
|
.captures()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| (query.capture_names()[c.index as usize], c.node))
|
.map(|c| (query.capture_names()[c.index as usize], c.node))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
|
@ -5833,10 +5833,10 @@ fn test_consecutive_zero_or_modifiers() {
|
||||||
let mut len_1 = false;
|
let mut len_1 = false;
|
||||||
|
|
||||||
while let Some(m) = matches.next() {
|
while let Some(m) = matches.next() {
|
||||||
if m.captures.len() == 3 {
|
if m.captures().len() == 3 {
|
||||||
len_3 = true;
|
len_3 = true;
|
||||||
}
|
}
|
||||||
if m.captures.len() == 1 {
|
if m.captures().len() == 1 {
|
||||||
len_1 = true;
|
len_1 = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5898,7 +5898,7 @@ fn test_query_max_start_depth_more() {
|
||||||
let query = Query::new(&language, "(compound_statement) @capture").unwrap();
|
let query = Query::new(&language, "(compound_statement) @capture").unwrap();
|
||||||
|
|
||||||
let mut matches = cursor.matches(&query, tree.root_node(), source.as_bytes());
|
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");
|
assert_eq!(node.kind(), "compound_statement");
|
||||||
|
|
||||||
for row in rows {
|
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 cursor = QueryCursor::new();
|
||||||
let mut captures = cursor.captures(&query, tree.root_node(), text);
|
let mut captures = cursor.captures(&query, tree.root_node(), text);
|
||||||
let (match_, idx) = captures.next().unwrap();
|
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!(capture.index as usize, *idx);
|
||||||
assert_eq!("comment", capture.node.kind());
|
assert_eq!("comment", capture.node.kind());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -800,7 +800,7 @@ impl<'a> HighlightIterLayer<'a> {
|
||||||
let next_start = self
|
let next_start = self
|
||||||
.captures
|
.captures
|
||||||
.peek()
|
.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();
|
let next_end = self.highlight_end_stack.last().copied();
|
||||||
match (next_start, next_end) {
|
match (next_start, next_end) {
|
||||||
(Some(start), Some(end)) => {
|
(Some(start), Some(end)) => {
|
||||||
|
|
@ -926,7 +926,7 @@ where
|
||||||
let range;
|
let range;
|
||||||
let layer = &mut self.layers[0];
|
let layer = &mut self.layers[0];
|
||||||
if let Some((next_match, capture_index)) = layer.captures.peek() {
|
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();
|
range = next_capture.node.byte_range();
|
||||||
|
|
||||||
// If any previous highlight ends before this node starts, then before
|
// 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 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 this capture represents an injection, then process the injection.
|
||||||
if match_.pattern_index < layer.config.locals_pattern_index {
|
if match_.pattern_index < layer.config.locals_pattern_index {
|
||||||
|
|
@ -1037,7 +1037,7 @@ where
|
||||||
let scope = layer.scope_stack.last_mut().unwrap();
|
let scope = layer.scope_stack.last_mut().unwrap();
|
||||||
|
|
||||||
let mut value_range = 0..0;
|
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 {
|
if Some(capture.index) == layer.config.local_def_value_capture_index {
|
||||||
value_range = capture.node.byte_range();
|
value_range = capture.node.byte_range();
|
||||||
}
|
}
|
||||||
|
|
@ -1080,7 +1080,7 @@ where
|
||||||
|
|
||||||
// Continue processing any additional matches for the same node.
|
// Continue processing any additional matches for the same node.
|
||||||
if let Some((next_match, next_capture_index)) = layer.captures.peek() {
|
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 {
|
if next_capture.node == capture.node {
|
||||||
capture = next_capture;
|
capture = next_capture;
|
||||||
match_ = layer.captures.next().unwrap().0;
|
match_ = layer.captures.next().unwrap().0;
|
||||||
|
|
@ -1110,7 +1110,7 @@ where
|
||||||
// captures are guaranteed to be for highlighting, not injections or
|
// captures are guaranteed to be for highlighting, not injections or
|
||||||
// local variables.
|
// local variables.
|
||||||
while let Some((next_match, next_capture_index)) = layer.captures.peek() {
|
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 {
|
if next_capture.node == capture.node {
|
||||||
let following_match = layer.captures.next().unwrap().0;
|
let following_match = layer.captures.next().unwrap().0;
|
||||||
// If the current node was found to be a local variable, then ignore
|
// 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 language_name = None;
|
||||||
let mut content_node = None;
|
let mut content_node = None;
|
||||||
|
|
||||||
for capture in query_match.captures {
|
for capture in query_match.captures() {
|
||||||
let index = Some(capture.index);
|
let index = Some(capture.index);
|
||||||
if index == language_capture_index {
|
if index == language_capture_index {
|
||||||
language_name = capture.node.utf8_text(source).ok();
|
language_name = capture.node.utf8_text(source).ok();
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ where
|
||||||
let pattern_info = &self.config.pattern_info[mat.pattern_index];
|
let pattern_info = &self.config.pattern_info[mat.pattern_index];
|
||||||
|
|
||||||
if mat.pattern_index < self.config.tags_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 index = Some(capture.index);
|
||||||
let range = capture.node.byte_range();
|
let range = capture.node.byte_range();
|
||||||
if index == self.config.local_scope_capture_index {
|
if index == self.config.local_scope_capture_index {
|
||||||
|
|
@ -405,7 +405,7 @@ where
|
||||||
let mut docs_adjacent_node = None;
|
let mut docs_adjacent_node = None;
|
||||||
let mut is_ignored = false;
|
let mut is_ignored = false;
|
||||||
|
|
||||||
for capture in mat.captures {
|
for capture in mat.captures() {
|
||||||
let index = Some(capture.index);
|
let index = Some(capture.index);
|
||||||
|
|
||||||
if index == self.config.ignore_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.
|
/// A match of a [`Query`] to a particular set of [`Node`]s.
|
||||||
pub struct QueryMatch<'cursor, 'tree> {
|
pub struct QueryMatch<'cursor, 'tree> {
|
||||||
pub pattern_index: usize,
|
pub pattern_index: usize,
|
||||||
pub captures: &'cursor [QueryCapture<'tree>],
|
captures: &'cursor [QueryCapture<'tree>],
|
||||||
id: u32,
|
id: u32,
|
||||||
cursor: *mut ffi::TSQueryCursor,
|
cursor: *mut ffi::TSQueryCursor,
|
||||||
}
|
}
|
||||||
|
|
@ -3434,6 +3434,11 @@ impl<'tree> QueryMatch<'_, 'tree> {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub const fn captures(&self) -> &[QueryCapture<'tree>] {
|
||||||
|
self.captures
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(alias = "ts_query_cursor_remove_match")]
|
#[doc(alias = "ts_query_cursor_remove_match")]
|
||||||
pub fn remove(&self) {
|
pub fn remove(&self) {
|
||||||
unsafe { ffi::ts_query_cursor_remove_match(self.cursor, self.id) }
|
unsafe { ffi::ts_query_cursor_remove_match(self.cursor, self.id) }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue