improve match bracket matching (#10613)

This commit is contained in:
Pascal Kuthe 2024-05-07 16:26:04 +02:00 committed by GitHub
parent 0432d9cf14
commit 5b8b2f4b9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 185 additions and 60 deletions

View file

@ -806,3 +806,129 @@ async fn test_select_prev_sibling() -> anyhow::Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn match_bracket() -> anyhow::Result<()> {
let rust_tests = vec![
// fwd
(
indoc! {r##"
fn foo(x: usize) -> usize { #[x|]# + 1 }
"##},
"mm",
indoc! {r##"
fn foo(x: usize) -> usize { x + 1 #[}|]#
"##},
),
// backward
(
indoc! {r##"
fn foo(x: usize) -> usize { #[x|]# + 1 }
"##},
"mmmm",
indoc! {r##"
fn foo(x: usize) -> usize #[{|]# x + 1 }
"##},
),
// avoid false positive inside string literal
(
indoc! {r##"
fn foo() -> &'static str { "(hello#[ |]#world)" }
"##},
"mm",
indoc! {r##"
fn foo() -> &'static str { "(hello world)#["|]# }
"##},
),
// make sure matching on quotes works
(
indoc! {r##"
fn foo() -> &'static str { "(hello#[ |]#world)" }
"##},
"mm",
indoc! {r##"
fn foo() -> &'static str { "(hello world)#["|]# }
"##},
),
// .. on both ends
(
indoc! {r##"
fn foo() -> &'static str { "(hello#[ |]#world)" }
"##},
"mmmm",
indoc! {r##"
fn foo() -> &'static str { #["|]#(hello world)" }
"##},
),
// match on siblings nodes
(
indoc! {r##"
fn foo(bar: Option<usize>) -> usize {
match bar {
Some(b#[a|]#r) => bar,
None => 42,
}
}
"##},
"mmmm",
indoc! {r##"
fn foo(bar: Option<usize>) -> usize {
match bar {
Some#[(|]#bar) => bar,
None => 42,
}
}
"##},
),
// gracefully handle multiple sibling brackets (usally for errors/incomplete syntax trees)
// in the past we selected the first > instead of the second > here
(
indoc! {r##"
fn foo() {
foo::<b#[a|]#r<>>
}
"##},
"mm",
indoc! {r##"
fn foo() {
foo::<bar<>#[>|]#
}
"##},
),
];
let python_tests = vec![
// python quotes have a slightly more complex syntax tree
// that triggerd a bug in an old implementation so we test
// them here
(
indoc! {r##"
foo_python = "mm does not#[ |]#work on this string"
"##},
"mm",
indoc! {r##"
foo_python = "mm does not work on this string#["|]#
"##},
),
(
indoc! {r##"
foo_python = "mm does not#[ |]#work on this string"
"##},
"mmmm",
indoc! {r##"
foo_python = #["|]#mm does not work on this string"
"##},
),
];
for test in rust_tests {
println!("{test:?}");
test_with_config(AppBuilder::new().with_file("foo.rs", None), test).await?;
}
for test in python_tests {
println!("{test:?}");
test_with_config(AppBuilder::new().with_file("foo.py", None), test).await?;
}
Ok(())
}