Unnamed repository; edit this file 'description' to name the repository.
Make `stringify!` prettify its input
This will insert whitespace if the invocation is inside another macro
Jonas Schievink 2021-09-28
parent f22eea9 · commit d05eae6
-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 9293b45064..297497ac1b 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 fc1ac17213..d903725d88 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 088cc694e8..ff4976d0cb 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 8dfd65ade1..56f9853399 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 562ee69e37..b0c2681f71 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 f457881f2e..66180bb156 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
+}