aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/quote.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/quote.rs')
-rw-r--r--crates/ra_hir_expand/src/quote.rs40
1 files changed, 32 insertions, 8 deletions
diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs
index 65a35e52f..4de219ce4 100644
--- a/crates/ra_hir_expand/src/quote.rs
+++ b/crates/ra_hir_expand/src/quote.rs
@@ -16,7 +16,10 @@ macro_rules! __quote {
16 { 16 {
17 let children = $crate::__quote!($($tt)*); 17 let children = $crate::__quote!($($tt)*);
18 let subtree = tt::Subtree { 18 let subtree = tt::Subtree {
19 delimiter: tt::Delimiter::$delim, 19 delimiter: Some(tt::Delimiter {
20 kind: tt::DelimiterKind::$delim,
21 id: tt::TokenId::unspecified(),
22 }),
20 token_trees: $crate::quote::IntoTt::to_tokens(children), 23 token_trees: $crate::quote::IntoTt::to_tokens(children),
21 }; 24 };
22 subtree 25 subtree
@@ -29,6 +32,7 @@ macro_rules! __quote {
29 tt::Leaf::Punct(tt::Punct { 32 tt::Leaf::Punct(tt::Punct {
30 char: $first, 33 char: $first,
31 spacing: tt::Spacing::Alone, 34 spacing: tt::Spacing::Alone,
35 id: tt::TokenId::unspecified(),
32 }).into() 36 }).into()
33 ] 37 ]
34 } 38 }
@@ -40,10 +44,12 @@ macro_rules! __quote {
40 tt::Leaf::Punct(tt::Punct { 44 tt::Leaf::Punct(tt::Punct {
41 char: $first, 45 char: $first,
42 spacing: tt::Spacing::Joint, 46 spacing: tt::Spacing::Joint,
47 id: tt::TokenId::unspecified(),
43 }).into(), 48 }).into(),
44 tt::Leaf::Punct(tt::Punct { 49 tt::Leaf::Punct(tt::Punct {
45 char: $sec, 50 char: $sec,
46 spacing: tt::Spacing::Alone, 51 spacing: tt::Spacing::Alone,
52 id: tt::TokenId::unspecified(),
47 }).into() 53 }).into()
48 ] 54 ]
49 } 55 }
@@ -60,6 +66,15 @@ macro_rules! __quote {
60 } 66 }
61 }; 67 };
62 68
69 ( ## $first:ident $($tail:tt)* ) => {
70 {
71 let mut tokens = $first.into_iter().map($crate::quote::ToTokenTree::to_token).collect::<Vec<tt::TokenTree>>();
72 let mut tail_tokens = $crate::quote::IntoTt::to_tokens($crate::__quote!($($tail)*));
73 tokens.append(&mut tail_tokens);
74 tokens
75 }
76 };
77
63 // Brace 78 // Brace
64 ( { $($tt:tt)* } ) => { $crate::__quote!(@SUBTREE Brace $($tt)*) }; 79 ( { $($tt:tt)* } ) => { $crate::__quote!(@SUBTREE Brace $($tt)*) };
65 // Bracket 80 // Bracket
@@ -85,7 +100,10 @@ macro_rules! __quote {
85 ( & ) => {$crate::__quote!(@PUNCT '&')}; 100 ( & ) => {$crate::__quote!(@PUNCT '&')};
86 ( , ) => {$crate::__quote!(@PUNCT ',')}; 101 ( , ) => {$crate::__quote!(@PUNCT ',')};
87 ( : ) => {$crate::__quote!(@PUNCT ':')}; 102 ( : ) => {$crate::__quote!(@PUNCT ':')};
103 ( :: ) => {$crate::__quote!(@PUNCT ':', ':')};
88 ( . ) => {$crate::__quote!(@PUNCT '.')}; 104 ( . ) => {$crate::__quote!(@PUNCT '.')};
105 ( < ) => {$crate::__quote!(@PUNCT '<')};
106 ( > ) => {$crate::__quote!(@PUNCT '>')};
89 107
90 ( $first:tt $($tail:tt)+ ) => { 108 ( $first:tt $($tail:tt)+ ) => {
91 { 109 {
@@ -114,7 +132,7 @@ pub(crate) trait IntoTt {
114 132
115impl IntoTt for Vec<tt::TokenTree> { 133impl IntoTt for Vec<tt::TokenTree> {
116 fn to_subtree(self) -> tt::Subtree { 134 fn to_subtree(self) -> tt::Subtree {
117 tt::Subtree { delimiter: tt::Delimiter::None, token_trees: self } 135 tt::Subtree { delimiter: None, token_trees: self }
118 } 136 }
119 137
120 fn to_tokens(self) -> Vec<tt::TokenTree> { 138 fn to_tokens(self) -> Vec<tt::TokenTree> {
@@ -169,15 +187,15 @@ macro_rules! impl_to_to_tokentrees {
169} 187}
170 188
171impl_to_to_tokentrees! { 189impl_to_to_tokentrees! {
172 u32 => self { tt::Literal{text: self.to_string().into()} }; 190 u32 => self { tt::Literal{text: self.to_string().into(), id: tt::TokenId::unspecified()} };
173 usize => self { tt::Literal{text: self.to_string().into()}}; 191 usize => self { tt::Literal{text: self.to_string().into(), id: tt::TokenId::unspecified()}};
174 i32 => self { tt::Literal{text: self.to_string().into()}}; 192 i32 => self { tt::Literal{text: self.to_string().into(), id: tt::TokenId::unspecified()}};
175 tt::Leaf => self { self }; 193 tt::Leaf => self { self };
176 tt::Literal => self { self }; 194 tt::Literal => self { self };
177 tt::Ident => self { self }; 195 tt::Ident => self { self };
178 tt::Punct => self { self }; 196 tt::Punct => self { self };
179 &str => self { tt::Literal{text: format!("{:?}", self.escape_default().to_string()).into()}}; 197 &str => self { tt::Literal{text: format!("{:?}", self.escape_default().to_string()).into(), id: tt::TokenId::unspecified()}};
180 String => self { tt::Literal{text: format!("{:?}", self.escape_default().to_string()).into()}} 198 String => self { tt::Literal{text: format!("{:?}", self.escape_default().to_string()).into(), id: tt::TokenId::unspecified()}}
181} 199}
182 200
183#[cfg(test)] 201#[cfg(test)]
@@ -244,7 +262,13 @@ mod tests {
244 let fields = 262 let fields =
245 fields.iter().map(|it| quote!(#it: self.#it.clone(), ).token_trees.clone()).flatten(); 263 fields.iter().map(|it| quote!(#it: self.#it.clone(), ).token_trees.clone()).flatten();
246 264
247 let list = tt::Subtree { delimiter: tt::Delimiter::Brace, token_trees: fields.collect() }; 265 let list = tt::Subtree {
266 delimiter: Some(tt::Delimiter {
267 kind: tt::DelimiterKind::Brace,
268 id: tt::TokenId::unspecified(),
269 }),
270 token_trees: fields.collect(),
271 };
248 272
249 let quoted = quote! { 273 let quoted = quote! {
250 impl Clone for #struct_name { 274 impl Clone for #struct_name {