fix(rust): EqCapture accepted cases where number of captured nodes differed by one
Problem: When using alternations, the `#eq?` predicate does not always use the same capture name. Solution: Iterate the left and right captured nodes more independently.
This commit is contained in:
parent
0a7274678a
commit
79177a1cd5
2 changed files with 60 additions and 3 deletions
|
|
@ -2999,6 +2999,61 @@ fn test_query_matches_with_deeply_nested_patterns_with_fields() {
|
|||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_query_matches_with_alternations_and_predicates() {
|
||||
allocations::record(|| {
|
||||
let language = get_language("java");
|
||||
let query = Query::new(
|
||||
&language,
|
||||
"
|
||||
(block
|
||||
[
|
||||
(local_variable_declaration
|
||||
(variable_declarator
|
||||
(identifier) @def.a
|
||||
(string_literal) @lit.a
|
||||
)
|
||||
)
|
||||
(local_variable_declaration
|
||||
(variable_declarator
|
||||
(identifier) @def.b
|
||||
(null_literal) @lit.b
|
||||
)
|
||||
)
|
||||
]
|
||||
(expression_statement
|
||||
(method_invocation [
|
||||
(argument_list
|
||||
(identifier) @ref.a
|
||||
(string_literal)
|
||||
)
|
||||
(argument_list
|
||||
(null_literal)
|
||||
(identifier) @ref.b
|
||||
)
|
||||
])
|
||||
)
|
||||
(#eq? @def.a @ref.a )
|
||||
(#eq? @def.b @ref.b )
|
||||
)
|
||||
",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_query_matches(
|
||||
&language,
|
||||
&query,
|
||||
r#"
|
||||
void test() {
|
||||
int a = "foo";
|
||||
f(null, b);
|
||||
}
|
||||
"#,
|
||||
&[],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_query_matches_with_indefinite_step_containing_no_captures() {
|
||||
allocations::record(|| {
|
||||
|
|
|
|||
|
|
@ -3355,9 +3355,11 @@ impl<'tree> QueryMatch<'_, 'tree> {
|
|||
.iter()
|
||||
.all(|predicate| match predicate {
|
||||
TextPredicateCapture::EqCapture(i, j, is_positive, match_all_nodes) => {
|
||||
let mut nodes_1 = self.nodes_for_capture_index(*i);
|
||||
let mut nodes_2 = self.nodes_for_capture_index(*j);
|
||||
while let (Some(node1), Some(node2)) = (nodes_1.next(), nodes_2.next()) {
|
||||
let mut nodes_1 = self.nodes_for_capture_index(*i).peekable();
|
||||
let mut nodes_2 = self.nodes_for_capture_index(*j).peekable();
|
||||
while nodes_1.peek().is_some() && nodes_2.peek().is_some() {
|
||||
let node1 = nodes_1.next().unwrap();
|
||||
let node2 = nodes_2.next().unwrap();
|
||||
let mut text1 = text_provider.text(node1);
|
||||
let mut text2 = text_provider.text(node2);
|
||||
let text1 = node_text1.get_text(&mut text1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue