about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2021-09-27 19:02:03 +0200
committerJonas Schievink <jonasschievink@gmail.com>2021-09-27 19:02:03 +0200
commitd05eae6ada1178b3c455be9731dd8b5db7804706 (patch)
tree0e919719f18e9400e60eec7bfca7e3a456e8f573
parentf22eea905358efafc68c6c3de2bae05fb30b68a5 (diff)
downloadrust-d05eae6ada1178b3c455be9731dd8b5db7804706.tar.gz
rust-d05eae6ada1178b3c455be9731dd8b5db7804706.zip
Make `stringify!` prettify its input
This will insert whitespace if the invocation is inside another macro
-rw-r--r--crates/hir_expand/src/builtin_macro.rs29
-rw-r--r--crates/hir_expand/src/lib.rs2
-rw-r--r--crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs39
-rw-r--r--crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs39
-rw-r--r--crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs39
-rw-r--r--crates/tt/src/lib.rs33
6 files changed, 48 insertions, 133 deletions
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 9293b450646..297497ac1bf 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -1,7 +1,7 @@
 //! Builtin macro
 use crate::{
     db::AstDatabase, name, quote, AstId, CrateId, MacroCallId, MacroCallLoc, MacroDefId,
-    MacroDefKind, TextSize,
+    MacroDefKind,
 };
 
 use base_db::{AnchoredPath, Edition, FileId};
@@ -148,25 +148,14 @@ fn line_expand(
 }
 
 fn stringify_expand(
-    db: &dyn AstDatabase,
-    id: MacroCallId,
-    _tt: &tt::Subtree,
+    _db: &dyn AstDatabase,
+    _id: MacroCallId,
+    tt: &tt::Subtree,
 ) -> ExpandResult<tt::Subtree> {
-    let loc = db.lookup_intern_macro(id);
-
-    let macro_content = {
-        let arg = match loc.kind.arg(db) {
-            Some(arg) => arg,
-            None => return ExpandResult::only_err(mbe::ExpandError::UnexpectedToken),
-        };
-        let macro_args = arg;
-        let text = macro_args.text();
-        let without_parens = TextSize::of('(')..text.len() - TextSize::of(')');
-        text.slice(without_parens).to_string()
-    };
+    let pretty = tt::pretty(&tt.token_trees);
 
     let expanded = quote! {
-        #macro_content
+        #pretty
     };
 
     ExpandResult::ok(expanded)
@@ -685,7 +674,11 @@ mod tests {
             r#"
             #[rustc_builtin_macro]
             macro_rules! stringify {() => {}}
-            stringify!(a b c)
+            stringify!(
+                a
+                b
+                c
+            )
             "#,
             expect![["\"a b c\""]],
         );
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index fc1ac172136..d903725d884 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -26,7 +26,7 @@ use base_db::{impl_intern_key, salsa, CrateId, FileId, FileRange};
 use syntax::{
     algo::skip_trivia_token,
     ast::{self, AstNode, HasAttrs},
-    Direction, SyntaxNode, SyntaxToken, TextRange, TextSize,
+    Direction, SyntaxNode, SyntaxToken, TextRange,
 };
 
 use crate::{
diff --git a/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs b/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs
index 088cc694e83..ff4976d0cbf 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs
@@ -199,44 +199,7 @@ pub mod token_stream {
 
     impl ToString for TokenStream {
         fn to_string(&self) -> String {
-            return tokentrees_to_text(&self.token_trees[..]);
-
-            fn tokentrees_to_text(tkns: &[tt::TokenTree]) -> String {
-                tkns.iter()
-                    .fold((String::new(), true), |(last, last_to_joint), tkn| {
-                        let s = [last, tokentree_to_text(tkn)].join(if last_to_joint {
-                            ""
-                        } else {
-                            " "
-                        });
-                        let mut is_joint = false;
-                        if let tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) = tkn {
-                            if punct.spacing == tt::Spacing::Joint {
-                                is_joint = true;
-                            }
-                        }
-                        (s, is_joint)
-                    })
-                    .0
-            }
-
-            fn tokentree_to_text(tkn: &tt::TokenTree) -> String {
-                match tkn {
-                    tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident.text.clone().into(),
-                    tt::TokenTree::Leaf(tt::Leaf::Literal(literal)) => literal.text.clone().into(),
-                    tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => format!("{}", punct.char),
-                    tt::TokenTree::Subtree(subtree) => {
-                        let content = tokentrees_to_text(&subtree.token_trees);
-                        let (open, close) = match subtree.delimiter.map(|it| it.kind) {
-                            None => ("", ""),
-                            Some(tt::DelimiterKind::Brace) => ("{", "}"),
-                            Some(tt::DelimiterKind::Parenthesis) => ("(", ")"),
-                            Some(tt::DelimiterKind::Bracket) => ("[", "]"),
-                        };
-                        format!("{}{}{}", open, content, close)
-                    }
-                }
-            }
+            tt::pretty(&self.token_trees)
         }
     }
 
diff --git a/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs b/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs
index 8dfd65ade1c..56f9853399c 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs
@@ -199,44 +199,7 @@ pub mod token_stream {
 
     impl ToString for TokenStream {
         fn to_string(&self) -> String {
-            return tokentrees_to_text(&self.token_trees[..]);
-
-            fn tokentrees_to_text(tkns: &[tt::TokenTree]) -> String {
-                tkns.iter()
-                    .fold((String::new(), true), |(last, last_to_joint), tkn| {
-                        let s = [last, tokentree_to_text(tkn)].join(if last_to_joint {
-                            ""
-                        } else {
-                            " "
-                        });
-                        let mut is_joint = false;
-                        if let tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) = tkn {
-                            if punct.spacing == tt::Spacing::Joint {
-                                is_joint = true;
-                            }
-                        }
-                        (s, is_joint)
-                    })
-                    .0
-            }
-
-            fn tokentree_to_text(tkn: &tt::TokenTree) -> String {
-                match tkn {
-                    tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident.text.clone().into(),
-                    tt::TokenTree::Leaf(tt::Leaf::Literal(literal)) => literal.text.clone().into(),
-                    tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => format!("{}", punct.char),
-                    tt::TokenTree::Subtree(subtree) => {
-                        let content = tokentrees_to_text(&subtree.token_trees);
-                        let (open, close) = match subtree.delimiter.map(|it| it.kind) {
-                            None => ("", ""),
-                            Some(tt::DelimiterKind::Brace) => ("{", "}"),
-                            Some(tt::DelimiterKind::Parenthesis) => ("(", ")"),
-                            Some(tt::DelimiterKind::Bracket) => ("[", "]"),
-                        };
-                        format!("{}{}{}", open, content, close)
-                    }
-                }
-            }
+            tt::pretty(&self.token_trees)
         }
     }
 
diff --git a/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs b/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs
index 562ee69e377..b0c2681f713 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs
@@ -199,44 +199,7 @@ pub mod token_stream {
 
     impl ToString for TokenStream {
         fn to_string(&self) -> String {
-            return tokentrees_to_text(&self.token_trees[..]);
-
-            fn tokentrees_to_text(tkns: &[tt::TokenTree]) -> String {
-                tkns.iter()
-                    .fold((String::new(), true), |(last, last_to_joint), tkn| {
-                        let s = [last, tokentree_to_text(tkn)].join(if last_to_joint {
-                            ""
-                        } else {
-                            " "
-                        });
-                        let mut is_joint = false;
-                        if let tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) = tkn {
-                            if punct.spacing == tt::Spacing::Joint {
-                                is_joint = true;
-                            }
-                        }
-                        (s, is_joint)
-                    })
-                    .0
-            }
-
-            fn tokentree_to_text(tkn: &tt::TokenTree) -> String {
-                match tkn {
-                    tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident.text.clone().into(),
-                    tt::TokenTree::Leaf(tt::Leaf::Literal(literal)) => literal.text.clone().into(),
-                    tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => format!("{}", punct.char),
-                    tt::TokenTree::Subtree(subtree) => {
-                        let content = tokentrees_to_text(&subtree.token_trees);
-                        let (open, close) = match subtree.delimiter.map(|it| it.kind) {
-                            None => ("", ""),
-                            Some(tt::DelimiterKind::Brace) => ("{", "}"),
-                            Some(tt::DelimiterKind::Parenthesis) => ("(", ")"),
-                            Some(tt::DelimiterKind::Bracket) => ("[", "]"),
-                        };
-                        format!("{}{}{}", open, content, close)
-                    }
-                }
-            }
+            tt::pretty(&self.token_trees)
         }
     }
 
diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs
index f457881f2eb..66180bb1561 100644
--- a/crates/tt/src/lib.rs
+++ b/crates/tt/src/lib.rs
@@ -274,3 +274,36 @@ impl Subtree {
 }
 
 pub mod buffer;
+
+pub fn pretty(tkns: &[TokenTree]) -> String {
+    fn tokentree_to_text(tkn: &TokenTree) -> String {
+        match tkn {
+            TokenTree::Leaf(Leaf::Ident(ident)) => ident.text.clone().into(),
+            TokenTree::Leaf(Leaf::Literal(literal)) => literal.text.clone().into(),
+            TokenTree::Leaf(Leaf::Punct(punct)) => format!("{}", punct.char),
+            TokenTree::Subtree(subtree) => {
+                let content = pretty(&subtree.token_trees);
+                let (open, close) = match subtree.delimiter.map(|it| it.kind) {
+                    None => ("", ""),
+                    Some(DelimiterKind::Brace) => ("{", "}"),
+                    Some(DelimiterKind::Parenthesis) => ("(", ")"),
+                    Some(DelimiterKind::Bracket) => ("[", "]"),
+                };
+                format!("{}{}{}", open, content, close)
+            }
+        }
+    }
+
+    tkns.iter()
+        .fold((String::new(), true), |(last, last_to_joint), tkn| {
+            let s = [last, tokentree_to_text(tkn)].join(if last_to_joint { "" } else { " " });
+            let mut is_joint = false;
+            if let TokenTree::Leaf(Leaf::Punct(punct)) = tkn {
+                if punct.spacing == Spacing::Joint {
+                    is_joint = true;
+                }
+            }
+            (s, is_joint)
+        })
+        .0
+}