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 `( -> { -> [ -> (`. // Change macro delimiters in the order of `( -> { -> [ -> (`.
// //
// ``` // ```
// macro_rules! sth (); // macro_rules! sth {
// () => {};
// }
//
// sth! $0( ); // sth! $0( );
// ``` // ```
// -> // ->
// ``` // ```
// macro_rules! sth! (); // macro_rules! sth {
// () => {};
// }
//
// sth! { } // sth! { }
// ``` // ```
pub(crate) fn toggle_macro_delimiter(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { 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, RCur,
} }
enum MakroTypes { let makro = ctx.find_node_at_offset_with_descend::<ast::MacroCall>()?.clone_for_update();
MacroRules(ast::MacroRules), let makro_text_range = makro.syntax().text_range();
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 cursor_offset = ctx.offset(); let cursor_offset = ctx.offset();
let token_tree = match makro { let semicolon = makro.semicolon_token();
MakroTypes::MacroRules(mr) => mr.token_tree()?.clone_for_update(), let token_tree = makro.token_tree()?;
MakroTypes::MacroCall(md) => md.token_tree()?.clone_for_update(),
};
let token_tree_text_range = token_tree.syntax().text_range();
let ltoken = token_tree.left_delimiter_token()?; let ltoken = token_tree.left_delimiter_token()?;
let rtoken = token_tree.right_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 => { MacroDelims::LPar | MacroDelims::RPar => {
ted::replace(ltoken, make::token(T!['{'])); ted::replace(ltoken, make::token(T!['{']));
ted::replace(rtoken, make::token(T!['}'])); ted::replace(rtoken, make::token(T!['}']));
if let Some(sc) = semicolon {
ted::remove(sc);
}
} }
MacroDelims::LBra | MacroDelims::RBra => { MacroDelims::LBra | MacroDelims::RBra => {
ted::replace(ltoken, make::token(T!['('])); 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![']'])); 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( check_assist(
toggle_macro_delimiter, toggle_macro_delimiter,
r#" r#"
macro_rules! sth (); macro_rules! sth {
() => {};
}
sth! $0( ); sth! $0( );
"#, "#,
r#" r#"
macro_rules! sth (); macro_rules! sth {
sth! { }; () => {};
}
sth! { }
"#, "#,
) )
} }
@ -125,11 +127,17 @@ sth! { };
check_assist( check_assist(
toggle_macro_delimiter, toggle_macro_delimiter,
r#" r#"
macro_rules! sth (); macro_rules! sth {
() => {};
}
sth! $0{ }; sth! $0{ };
"#, "#,
r#" r#"
macro_rules! sth (); macro_rules! sth {
() => {};
}
sth! [ ]; sth! [ ];
"#, "#,
) )
@ -140,11 +148,17 @@ sth! [ ];
check_assist( check_assist(
toggle_macro_delimiter, toggle_macro_delimiter,
r#" r#"
macro_rules! sth (); macro_rules! sth {
() => {};
}
sth! $0[ ]; sth! $0[ ];
"#, "#,
r#" r#"
macro_rules! sth (); macro_rules! sth {
() => {};
}
sth! ( ); sth! ( );
"#, "#,
) )
@ -156,72 +170,87 @@ sth! ( );
toggle_macro_delimiter, toggle_macro_delimiter,
r#" r#"
mod abc { mod abc {
macro_rules! sth (); macro_rules! sth {
() => {};
}
sth! $0{ }; sth! $0{ };
} }
"#, "#,
r#" r#"
mod abc { mod abc {
macro_rules! sth (); macro_rules! sth {
() => {};
}
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] #[test]
fn test_unrelated_par() { fn test_unrelated_par() {
check_assist_not_applicable( check_assist_not_applicable(
toggle_macro_delimiter, toggle_macro_delimiter,
r#" r#"
macro_rules! sth [def$0()]; macro_rules! prt {
sth! ( ); ($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] #[test]
fn doctest_unmerge_match_arm() { fn doctest_unmerge_match_arm() {
check_doc_test( check_doc_test(