aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/expand_macro.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/expand_macro.rs')
-rw-r--r--crates/ide/src/expand_macro.rs46
1 files changed, 34 insertions, 12 deletions
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs
index ffb3a6f7d..be0ee03bf 100644
--- a/crates/ide/src/expand_macro.rs
+++ b/crates/ide/src/expand_macro.rs
@@ -1,3 +1,5 @@
1use std::iter;
2
1use hir::Semantics; 3use hir::Semantics;
2use ide_db::RootDatabase; 4use ide_db::RootDatabase;
3use syntax::{ 5use syntax::{
@@ -23,6 +25,8 @@ pub struct ExpandedMacro {
23// 25//
24// | VS Code | **Rust Analyzer: Expand macro recursively** 26// | VS Code | **Rust Analyzer: Expand macro recursively**
25// |=== 27// |===
28//
29// image::https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif[]
26pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> { 30pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> {
27 let sema = Semantics::new(db); 31 let sema = Semantics::new(db);
28 let file = sema.parse(position.file_id); 32 let file = sema.parse(position.file_id);
@@ -89,24 +93,42 @@ fn insert_whitespaces(syn: SyntaxNode) -> String {
89 let is_last = 93 let is_last =
90 |f: fn(SyntaxKind) -> bool, default| -> bool { last.map(f).unwrap_or(default) }; 94 |f: fn(SyntaxKind) -> bool, default| -> bool { last.map(f).unwrap_or(default) };
91 95
92 res += &match token.kind() { 96 match token.kind() {
93 k if is_text(k) && is_next(|it| !it.is_punct(), true) => token.text().to_string() + " ", 97 k if is_text(k) && is_next(|it| !it.is_punct(), true) => {
98 res.push_str(token.text());
99 res.push(' ');
100 }
94 L_CURLY if is_next(|it| it != R_CURLY, true) => { 101 L_CURLY if is_next(|it| it != R_CURLY, true) => {
95 indent += 1; 102 indent += 1;
96 let leading_space = if is_last(is_text, false) { " " } else { "" }; 103 if is_last(is_text, false) {
97 format!("{}{{\n{}", leading_space, " ".repeat(indent)) 104 res.push(' ');
105 }
106 res.push_str("{\n");
107 res.extend(iter::repeat(" ").take(2 * indent));
98 } 108 }
99 R_CURLY if is_last(|it| it != L_CURLY, true) => { 109 R_CURLY if is_last(|it| it != L_CURLY, true) => {
100 indent = indent.saturating_sub(1); 110 indent = indent.saturating_sub(1);
101 format!("\n{}}}", " ".repeat(indent)) 111 res.push('\n');
112 res.extend(iter::repeat(" ").take(2 * indent));
113 res.push_str("}");
102 } 114 }
103 R_CURLY => format!("}}\n{}", " ".repeat(indent)), 115 R_CURLY => {
104 T![;] => format!(";\n{}", " ".repeat(indent)), 116 res.push_str("}\n");
105 T![->] => " -> ".to_string(), 117 res.extend(iter::repeat(" ").take(2 * indent));
106 T![=] => " = ".to_string(), 118 }
107 T![=>] => " => ".to_string(), 119 LIFETIME_IDENT if is_next(|it| it == IDENT, true) => {
108 _ => token.text().to_string(), 120 res.push_str(token.text());
109 }; 121 res.push(' ');
122 }
123 T![;] => {
124 res.push_str(";\n");
125 res.extend(iter::repeat(" ").take(2 * indent));
126 }
127 T![->] => res.push_str(" -> "),
128 T![=] => res.push_str(" = "),
129 T![=>] => res.push_str(" => "),
130 _ => res.push_str(token.text()),
131 }
110 132
111 last = Some(token.kind()); 133 last = Some(token.kind());
112 } 134 }