fix(lib): propagate last_child status to pattern alternatives in queries
Previously, when a pattern was marked as the last child in a query, its alternatives weren't marked similarly, causing incorrect matching behavior. Now, the `last_child` status is properly propagated through all alternatives.
This commit is contained in:
parent
f8e77aa99d
commit
a7e6d01144
2 changed files with 92 additions and 1 deletions
|
|
@ -5442,3 +5442,81 @@ fn test_wildcard_behavior_before_anchor() {
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pattern_alternatives_follow_last_child_constraint() {
|
||||
let language = get_language("rust");
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(&language).unwrap();
|
||||
|
||||
let code = "
|
||||
fn f() {
|
||||
if a {} // <- should NOT match
|
||||
if b {}
|
||||
}";
|
||||
|
||||
let tree = parser.parse(code, None).unwrap();
|
||||
let mut cursor = QueryCursor::new();
|
||||
|
||||
let query = Query::new(
|
||||
&language,
|
||||
"(block
|
||||
[
|
||||
(type_cast_expression)
|
||||
(expression_statement)
|
||||
] @last
|
||||
.
|
||||
)",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let matches = {
|
||||
let root_node = tree.root_node();
|
||||
let matches = cursor.matches(&query, root_node, code.as_bytes());
|
||||
collect_matches(matches, &query, code)
|
||||
.into_iter()
|
||||
.map(|(i, m)| {
|
||||
(
|
||||
i,
|
||||
m.into_iter()
|
||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
let flipped_query = Query::new(
|
||||
&language,
|
||||
"(block
|
||||
[
|
||||
(expression_statement)
|
||||
(type_cast_expression)
|
||||
] @last
|
||||
.
|
||||
)",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let flipped_matches = {
|
||||
let root_node = tree.root_node();
|
||||
let matches = cursor.matches(&flipped_query, root_node, code.as_bytes());
|
||||
collect_matches(matches, &flipped_query, code)
|
||||
.into_iter()
|
||||
.map(|(i, m)| {
|
||||
(
|
||||
i,
|
||||
m.into_iter()
|
||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
matches,
|
||||
vec![(0, vec![(String::from("last"), String::from("if b {}"))])]
|
||||
);
|
||||
assert_eq!(matches, flipped_matches);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue