aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-31 15:51:17 +0000
committerAleksey Kladov <[email protected]>2019-01-31 20:23:30 +0000
commitad80a0c551458de7d27a98d182d7f559de04f291 (patch)
tree20a3e85a30a45365fe31360cb57b4f53a17b9a28 /crates/ra_hir
parent59347388541388347e86de9718bd69994c113203 (diff)
preserve token spacing
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/macros.rs44
1 files changed, 29 insertions, 15 deletions
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs
index 059543bf2..e6ba8c08f 100644
--- a/crates/ra_hir/src/macros.rs
+++ b/crates/ra_hir/src/macros.rs
@@ -218,14 +218,28 @@ fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> {
218 continue; 218 continue;
219 } 219 }
220 if child.kind().is_punct() { 220 if child.kind().is_punct() {
221 let leaves = child 221 let mut prev = None;
222 .leaf_text() 222 for char in child.leaf_text().unwrap().chars() {
223 .unwrap() 223 if let Some(char) = prev {
224 .chars() 224 token_trees.push(
225 .map(|char| tt::Punct { char }) 225 tt::Leaf::from(tt::Punct {
226 .map(tt::Leaf::from) 226 char,
227 .map(tt::TokenTree::from); 227 spacing: tt::Spacing::Joint,
228 token_trees.extend(leaves); 228 })
229 .into(),
230 );
231 }
232 prev = Some(char)
233 }
234 if let Some(char) = prev {
235 token_trees.push(
236 tt::Leaf::from(tt::Punct {
237 char,
238 spacing: tt::Spacing::Alone,
239 })
240 .into(),
241 );
242 }
229 } else { 243 } else {
230 let child: tt::TokenTree = if child.kind() == TOKEN_TREE { 244 let child: tt::TokenTree = if child.kind() == TOKEN_TREE {
231 convert_tt(child)?.into() 245 convert_tt(child)?.into()
@@ -254,7 +268,7 @@ fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> {
254 268
255#[test] 269#[test]
256fn test_convert_tt() { 270fn test_convert_tt() {
257 let macro_defenition = r#" 271 let macro_definition = r#"
258macro_rules! impl_froms { 272macro_rules! impl_froms {
259 ($e:ident: $($v:ident),*) => { 273 ($e:ident: $($v:ident),*) => {
260 $( 274 $(
@@ -272,8 +286,8 @@ macro_rules! impl_froms {
272impl_froms!(TokenTree: Leaf, Subtree); 286impl_froms!(TokenTree: Leaf, Subtree);
273"#; 287"#;
274 288
275 let source_file = ast::SourceFile::parse(macro_defenition); 289 let source_file = ast::SourceFile::parse(macro_definition);
276 let macro_defenition = source_file 290 let macro_definition = source_file
277 .syntax() 291 .syntax()
278 .descendants() 292 .descendants()
279 .find_map(ast::MacroCall::cast) 293 .find_map(ast::MacroCall::cast)
@@ -286,13 +300,13 @@ impl_froms!(TokenTree: Leaf, Subtree);
286 .find_map(ast::MacroCall::cast) 300 .find_map(ast::MacroCall::cast)
287 .unwrap(); 301 .unwrap();
288 302
289 let defenition_tt = macro_call_to_tt(macro_defenition).unwrap(); 303 let definition_tt = macro_call_to_tt(macro_definition).unwrap();
290 let invocation_tt = macro_call_to_tt(macro_invocation).unwrap(); 304 let invocation_tt = macro_call_to_tt(macro_invocation).unwrap();
291 let mbe = mbe::parse(&defenition_tt).unwrap(); 305 let mbe = mbe::parse(&definition_tt).unwrap();
292 let expansion = mbe::exapnd(&mbe, &invocation_tt).unwrap(); 306 let expansion = mbe::exapnd(&mbe, &invocation_tt).unwrap();
293 assert_eq!( 307 assert_eq!(
294 expansion.to_string(), 308 expansion.to_string(),
295 "{(impl From < Leaf > for TokenTree {fn from (it : Leaf) - > TokenTree {TokenTree : : Leaf (it)}}) \ 309 "{(impl From < Leaf > for TokenTree {fn from (it : Leaf) -> TokenTree {TokenTree :: Leaf (it)}}) \
296 (impl From < Subtree > for TokenTree {fn from (it : Subtree) - > TokenTree {TokenTree : : Subtree (it)}})}" 310 (impl From < Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree :: Subtree (it)}})}"
297 ) 311 )
298} 312}