feat(lib): add ts_query_cursor_set_max_start_depth query API
This allows configuring cursors from traversing too deep into a tree.
This commit is contained in:
parent
2c8861d5ca
commit
1e81a1b67f
5 changed files with 144 additions and 8 deletions
|
|
@ -4469,6 +4469,103 @@ fn test_capture_quantifiers() {
|
|||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_query_max_start_depth() {
|
||||
struct Row {
|
||||
description: &'static str,
|
||||
pattern: &'static str,
|
||||
depth: u32,
|
||||
matches: &'static [(usize, &'static [(&'static str, &'static str)])],
|
||||
}
|
||||
|
||||
let source = r#"
|
||||
if (a1 && a2) {
|
||||
if (b1 && b2) { }
|
||||
if (c) { }
|
||||
}
|
||||
if (d) {
|
||||
if (e1 && e2) { }
|
||||
if (f) { }
|
||||
}
|
||||
"#;
|
||||
|
||||
let rows = &[
|
||||
Row {
|
||||
description: "depth 0: match none",
|
||||
depth: 0,
|
||||
pattern: r#"
|
||||
(if_statement) @capture
|
||||
"#,
|
||||
matches: &[]
|
||||
},
|
||||
Row {
|
||||
description: "depth 1: match 2 if statements at the top level",
|
||||
depth: 1,
|
||||
pattern: r#"
|
||||
(if_statement) @capture
|
||||
"#,
|
||||
matches : &[
|
||||
(0, &[("capture", "if (a1 && a2) {\n if (b1 && b2) { }\n if (c) { }\n }")]),
|
||||
(0, &[("capture", "if (d) {\n if (e1 && e2) { }\n if (f) { }\n }")])
|
||||
]
|
||||
},
|
||||
Row {
|
||||
description: "depth 1 with deep pattern: match the only the first if statement",
|
||||
depth: 1,
|
||||
pattern: r#"
|
||||
(if_statement
|
||||
condition: (parenthesized_expression
|
||||
(binary_expression)
|
||||
)
|
||||
) @capture
|
||||
"#,
|
||||
matches: &[
|
||||
(0, &[("capture", "if (a1 && a2) {\n if (b1 && b2) { }\n if (c) { }\n }")]),
|
||||
]
|
||||
},
|
||||
Row {
|
||||
description: "depth 3 with deep pattern: match all if statements with a binexpr condition",
|
||||
depth: 3,
|
||||
pattern: r#"
|
||||
(if_statement
|
||||
condition: (parenthesized_expression
|
||||
(binary_expression)
|
||||
)
|
||||
) @capture
|
||||
"#,
|
||||
matches: &[
|
||||
(0, &[("capture", "if (a1 && a2) {\n if (b1 && b2) { }\n if (c) { }\n }")]),
|
||||
(0, &[("capture", "if (b1 && b2) { }")]),
|
||||
(0, &[("capture", "if (e1 && e2) { }")])
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
allocations::record(|| {
|
||||
let language = get_language("c");
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(language).unwrap();
|
||||
let tree = parser.parse(source, None).unwrap();
|
||||
let mut cursor = QueryCursor::new();
|
||||
|
||||
for row in rows.iter() {
|
||||
eprintln!(" query example: {:?}", row.description);
|
||||
|
||||
let query = Query::new(language, row.pattern).unwrap();
|
||||
cursor.set_max_start_depth(row.depth);
|
||||
|
||||
let matches = cursor.matches(&query, tree.root_node(), source.as_bytes());
|
||||
let expected = row
|
||||
.matches
|
||||
.iter()
|
||||
.map(|x| (x.0, x.1.to_vec()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(collect_matches(matches, &query, source), expected);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn assert_query_matches(
|
||||
language: Language,
|
||||
query: &Query,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue