Make toggle_macro_delimiters work only for macro_calls

This commit is contained in:
Ali Bektas 2024-08-02 02:00:26 +02:00
parent 0a4ea1ed8f
commit ed865a60bf
2 changed files with 126 additions and 76 deletions

View file

@ -11,12 +11,18 @@ use crate::{AssistContext, Assists};
// Change macro delimiters in the order of `( -> { -> [ -> (`.
//
// ```
// macro_rules! sth ();
// macro_rules! sth {
// () => {};
// }
//
// sth! $0( );
// ```
// ->
// ```
// macro_rules! sth! ();
// macro_rules! sth {
// () => {};
// }
//
// sth! { }
// ```
pub(crate) fn toggle_macro_delimiter(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
@ -30,26 +36,13 @@ pub(crate) fn toggle_macro_delimiter(acc: &mut Assists, ctx: &AssistContext<'_>)
RCur,
}
enum MakroTypes {
MacroRules(ast::MacroRules),
MacroCall(ast::MacroCall),
}
let makro = if let Some(mc) = ctx.find_node_at_offset_with_descend::<ast::MacroCall>() {
MakroTypes::MacroCall(mc)
} else if let Some(mr) = ctx.find_node_at_offset_with_descend::<ast::MacroRules>() {
MakroTypes::MacroRules(mr)
} else {
return None;
};
let makro = ctx.find_node_at_offset_with_descend::<ast::MacroCall>()?.clone_for_update();
let makro_text_range = makro.syntax().text_range();
let cursor_offset = ctx.offset();
let token_tree = match makro {
MakroTypes::MacroRules(mr) => mr.token_tree()?.clone_for_update(),
MakroTypes::MacroCall(md) => md.token_tree()?.clone_for_update(),
};
let semicolon = makro.semicolon_token();
let token_tree = makro.token_tree()?;
let token_tree_text_range = token_tree.syntax().text_range();
let ltoken = token_tree.left_delimiter_token()?;
let rtoken = token_tree.right_delimiter_token()?;
@ -84,6 +77,9 @@ pub(crate) fn toggle_macro_delimiter(acc: &mut Assists, ctx: &AssistContext<'_>)
MacroDelims::LPar | MacroDelims::RPar => {
ted::replace(ltoken, make::token(T!['{']));
ted::replace(rtoken, make::token(T!['}']));
if let Some(sc) = semicolon {
ted::remove(sc);
}
}
MacroDelims::LBra | MacroDelims::RBra => {
ted::replace(ltoken, make::token(T!['(']));
@ -94,7 +90,7 @@ pub(crate) fn toggle_macro_delimiter(acc: &mut Assists, ctx: &AssistContext<'_>)
ted::replace(rtoken, make::token(T![']']));
}
}
builder.replace(token_tree_text_range, token_tree.syntax().text());
builder.replace(makro_text_range, makro.syntax().text());
},
)
}
@ -110,12 +106,18 @@ mod tests {
check_assist(
toggle_macro_delimiter,
r#"
macro_rules! sth ();
macro_rules! sth {
() => {};
}
sth! $0( );
"#,
r#"
macro_rules! sth ();
sth! { };
macro_rules! sth {
() => {};
}
sth! { }
"#,
)
}
@ -125,11 +127,17 @@ sth! { };
check_assist(
toggle_macro_delimiter,
r#"
macro_rules! sth ();
macro_rules! sth {
() => {};
}
sth! $0{ };
"#,
r#"
macro_rules! sth ();
macro_rules! sth {
() => {};
}
sth! [ ];
"#,
)
@ -140,11 +148,17 @@ sth! [ ];
check_assist(
toggle_macro_delimiter,
r#"
macro_rules! sth ();
macro_rules! sth {
() => {};
}
sth! $0[ ];
"#,
r#"
macro_rules! sth ();
macro_rules! sth {
() => {};
}
sth! ( );
"#,
)
@ -156,71 +170,86 @@ sth! ( );
toggle_macro_delimiter,
r#"
mod abc {
macro_rules! sth ();
macro_rules! sth {
() => {};
}
sth! $0{ };
}
"#,
r#"
mod abc {
macro_rules! sth ();
macro_rules! sth {
() => {};
}
sth! [ ];
}
"#,
)
}
#[test]
fn test_rules_par() {
check_assist(
toggle_macro_delimiter,
r#"
macro_rules! sth $0();
sth! ( );
"#,
r#"
macro_rules! sth {};
sth! ( );
"#,
)
}
#[test]
fn test_rules_braclets() {
check_assist(
toggle_macro_delimiter,
r#"
macro_rules! sth $0{};
sth! ( );
"#,
r#"
macro_rules! sth [];
sth! ( );
"#,
)
}
#[test]
fn test_rules_brackets() {
check_assist(
toggle_macro_delimiter,
r#"
macro_rules! sth $0[];
sth! ( );
"#,
r#"
macro_rules! sth ();
sth! ( );
"#,
)
}
#[test]
fn test_unrelated_par() {
check_assist_not_applicable(
toggle_macro_delimiter,
r#"
macro_rules! sth [def$0()];
sth! ( );
macro_rules! prt {
($e:expr) => {{
println!("{}", stringify! {$e});
}};
}
prt!(($03 + 5));
"#,
)
}
#[test]
fn test_longer_macros() {
check_assist(
toggle_macro_delimiter,
r#"
macro_rules! prt {
($e:expr) => {{
println!("{}", stringify! {$e});
}};
}
prt! $0((3 + 5));
"#,
r#"
macro_rules! prt {
($e:expr) => {{
println!("{}", stringify! {$e});
}};
}
prt! {(3 + 5)}
"#,
)
}
// FIXME @alibektas : Inner macro_call is not seen as such. So this doesn't work.
#[test]
fn test_nested_macros() {
check_assist_not_applicable(
toggle_macro_delimiter,
r#"
macro_rules! prt {
($e:expr) => {{
println!("{}", stringify! {$e});
}};
}
macro_rules! abc {
($e:expr) => {{
println!("{}", stringify! {$e});
}};
}
prt! {abc!($03 + 5)};
"#,
)
}

View file

@ -3091,6 +3091,27 @@ fn arithmetics {
)
}
#[test]
fn doctest_toggle_macro_delimiter() {
check_doc_test(
"toggle_macro_delimiter",
r#####"
macro_rules! sth {
() => {};
}
sth! $0( );
"#####,
r#####"
macro_rules! sth {
() => {};
}
sth! { }
"#####,
)
}
#[test]
fn doctest_unmerge_match_arm() {
check_doc_test(