Unnamed repository; edit this file 'description' to name the repository.
Make toggle_macro_delimiters work only for macro_calls
Ali Bektas 2024-08-02
parent 0a4ea1e · commit ed865a6
-rw-r--r--crates/ide-assists/src/handlers/toggle_macro_delimiter.rs153
-rw-r--r--crates/ide-assists/src/tests/generated.rs21
2 files changed, 112 insertions, 62 deletions
diff --git a/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs b/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
index 490957d04a..6fa5ff761f 100644
--- a/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
+++ b/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
@@ -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,13 +170,19 @@ 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! [ ];
}
"#,
@@ -170,58 +190,67 @@ mod abc {
}
#[test]
- fn test_rules_par() {
- check_assist(
+ fn test_unrelated_par() {
+ check_assist_not_applicable(
toggle_macro_delimiter,
r#"
-macro_rules! sth $0();
-sth! ( );
- "#,
- r#"
-macro_rules! sth {};
-sth! ( );
- "#,
- )
- }
+macro_rules! prt {
+ ($e:expr) => {{
+ println!("{}", stringify! {$e});
+ }};
+}
+
+prt!(($03 + 5));
- #[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() {
+ fn test_longer_macros() {
check_assist(
toggle_macro_delimiter,
r#"
-macro_rules! sth $0[];
-sth! ( );
- "#,
+macro_rules! prt {
+ ($e:expr) => {{
+ println!("{}", stringify! {$e});
+ }};
+}
+
+prt! $0((3 + 5));
+"#,
r#"
-macro_rules! sth ();
-sth! ( );
- "#,
+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_unrelated_par() {
+ fn test_nested_macros() {
check_assist_not_applicable(
toggle_macro_delimiter,
r#"
-macro_rules! sth [def$0()];
-sth! ( );
- "#,
+macro_rules! prt {
+ ($e:expr) => {{
+ println!("{}", stringify! {$e});
+ }};
+}
+
+macro_rules! abc {
+ ($e:expr) => {{
+ println!("{}", stringify! {$e});
+ }};
+}
+
+prt! {abc!($03 + 5)};
+"#,
)
}
}
diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs
index a2287b2977..05e1aff5f9 100644
--- a/crates/ide-assists/src/tests/generated.rs
+++ b/crates/ide-assists/src/tests/generated.rs
@@ -3092,6 +3092,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(
"unmerge_match_arm",