mirror of
https://github.com/tree-sitter/tree-sitter.git
synced 2026-09-10 07:36:22 -04:00
fix(query): correctly set a state's skipped_quantifier flag when a
zero quantifier skip is performed. The zero-skip branch currently sets skipped_quantifier unconditionally. That flag is correct only when the quantified step and its skip target are _siblings_ at the same query depth. Otherwise, setting it allows for a "leak" and disables unrelated, "outer" anchors.
This commit is contained in:
parent
5c2533bb7b
commit
42f33fe2f8
|
|
@ -1268,6 +1268,48 @@ function foo() {}
|
|||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_query_matches_with_anchor_after_nested_zero_quantifier() {
|
||||
allocations::record(|| {
|
||||
let language = get_language("javascript");
|
||||
let query = Query::new(
|
||||
&language,
|
||||
r#"
|
||||
(_
|
||||
(field_definition
|
||||
property: (_) @name
|
||||
value: (_)? @value
|
||||
) @field
|
||||
.
|
||||
";" @semicolon
|
||||
)
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_query_matches(
|
||||
&language,
|
||||
&query,
|
||||
"class Foo { bar; baz = 0; }",
|
||||
&[
|
||||
(
|
||||
0,
|
||||
vec![("field", "bar"), ("name", "bar"), ("semicolon", ";")],
|
||||
),
|
||||
(
|
||||
0,
|
||||
vec![
|
||||
("field", "baz = 0"),
|
||||
("name", "baz"),
|
||||
("value", "0"),
|
||||
("semicolon", ";"),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_query_matches_with_last_child_anchor_after_optional() {
|
||||
allocations::record(|| {
|
||||
|
|
|
|||
|
|
@ -4481,10 +4481,14 @@ static inline bool ts_query_cursor__advance(
|
|||
// nothing. How an adjacent anchor behaves then depends on where it sat:
|
||||
if (child_step->alternative_is_skip) {
|
||||
if (!child_step->is_immediate) {
|
||||
QueryStep *skip_target = array_get(
|
||||
&self->query->steps,
|
||||
child_step->alternative_index
|
||||
);
|
||||
// No leading anchor on the skipped step, so an immediately-following
|
||||
// anchor on the skip target is vacuous (`Q* . B` with zero `Q` lets
|
||||
// `B` match anywhere).
|
||||
copy->skipped_quantifier = true;
|
||||
copy->skipped_quantifier = skip_target->depth == child_step->depth;
|
||||
} else if (
|
||||
array_get(&self->query->steps, child_state->step_index - 1)->depth <
|
||||
child_step->depth
|
||||
|
|
|
|||
Loading…
Reference in a new issue