fix(lib): don't consider unfinished captures definite when the following step is immediate
When collecting captures, we were treating unfinished ones as definite even if they had pending immediate steps that weren't yet satisfied. Now we only mark a capture as definite if the pattern is guaranteed and there are no pending immediate steps to check.
This commit is contained in:
parent
5f379da544
commit
efc51a596c
2 changed files with 34 additions and 3 deletions
|
|
@ -5550,3 +5550,31 @@ function foo() {
|
|||
&[(0, vec![("part", "function foo() {\n \"bar\"\n}")])],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unfinished_captures_are_not_definite_with_pending_anchors() {
|
||||
let language = get_language("javascript");
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(&language).unwrap();
|
||||
|
||||
let source_code = "
|
||||
const foo = [
|
||||
1, 2, 3
|
||||
]
|
||||
";
|
||||
|
||||
let tree = parser.parse(source_code, None).unwrap();
|
||||
let query = Query::new(&language, r#"(array (_) @foo . "]")"#).unwrap();
|
||||
let mut matches_cursor = QueryCursor::new();
|
||||
let mut captures_cursor = QueryCursor::new();
|
||||
|
||||
let captures = captures_cursor.captures(&query, tree.root_node(), source_code.as_bytes());
|
||||
let captures = collect_captures(captures, &query, source_code);
|
||||
|
||||
let matches = matches_cursor.matches(&query, tree.root_node(), source_code.as_bytes());
|
||||
let matches = collect_matches(matches, &query, source_code);
|
||||
|
||||
assert_eq!(captures, vec![("foo", "3")]);
|
||||
assert_eq!(matches.len(), 1);
|
||||
assert_eq!(matches[0].1, captures);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3206,7 +3206,7 @@ static bool ts_query_cursor__first_in_progress_capture(
|
|||
uint32_t *state_index,
|
||||
uint32_t *byte_offset,
|
||||
uint32_t *pattern_index,
|
||||
bool *root_pattern_guaranteed
|
||||
bool *is_definite
|
||||
) {
|
||||
bool result = false;
|
||||
*state_index = UINT32_MAX;
|
||||
|
|
@ -3241,8 +3241,11 @@ static bool ts_query_cursor__first_in_progress_capture(
|
|||
(node_start_byte == *byte_offset && state->pattern_index < *pattern_index)
|
||||
) {
|
||||
QueryStep *step = &self->query->steps.contents[state->step_index];
|
||||
if (root_pattern_guaranteed) {
|
||||
*root_pattern_guaranteed = step->root_pattern_guaranteed;
|
||||
if (is_definite) {
|
||||
// We're being a bit conservative here by asserting that the following step
|
||||
// is not immediate, because this capture might end up being discarded if the
|
||||
// following symbol in the tree isn't the required symbol for this step.
|
||||
*is_definite = step->root_pattern_guaranteed && !step->is_immediate;
|
||||
} else if (step->root_pattern_guaranteed) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue