diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/db.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide_api/src/expand_macro.rs | 64 |
4 files changed, 93 insertions, 13 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index c42ceabdf..797f90d50 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -131,6 +131,7 @@ pub struct ReferenceDescriptor { | |||
131 | } | 131 | } |
132 | 132 | ||
133 | pub struct Expansion { | 133 | pub struct Expansion { |
134 | macro_file_kind: MacroFileKind, | ||
134 | macro_call_id: MacroCallId, | 135 | macro_call_id: MacroCallId, |
135 | } | 136 | } |
136 | 137 | ||
@@ -145,7 +146,7 @@ impl Expansion { | |||
145 | } | 146 | } |
146 | 147 | ||
147 | pub fn file_id(&self) -> HirFileId { | 148 | pub fn file_id(&self) -> HirFileId { |
148 | self.macro_call_id.as_file(MacroFileKind::Items) | 149 | self.macro_call_id.as_file(self.macro_file_kind) |
149 | } | 150 | } |
150 | } | 151 | } |
151 | 152 | ||
@@ -439,7 +440,10 @@ impl SourceAnalyzer { | |||
439 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | 440 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), |
440 | ); | 441 | ); |
441 | let macro_call_loc = MacroCallLoc { def, ast_id }; | 442 | let macro_call_loc = MacroCallLoc { def, ast_id }; |
442 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) | 443 | Some(Expansion { |
444 | macro_call_id: db.intern_macro(macro_call_loc), | ||
445 | macro_file_kind: to_macro_file_kind(macro_call.value), | ||
446 | }) | ||
443 | } | 447 | } |
444 | 448 | ||
445 | #[cfg(test)] | 449 | #[cfg(test)] |
@@ -538,3 +542,35 @@ fn adjust( | |||
538 | }) | 542 | }) |
539 | .map(|(_ptr, scope)| *scope) | 543 | .map(|(_ptr, scope)| *scope) |
540 | } | 544 | } |
545 | |||
546 | /// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to. | ||
547 | /// FIXME: Not completed | ||
548 | fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind { | ||
549 | let syn = macro_call.syntax(); | ||
550 | let parent = match syn.parent() { | ||
551 | Some(it) => it, | ||
552 | None => { | ||
553 | // FIXME: | ||
554 | // If it is root, which means the parent HirFile | ||
555 | // MacroKindFile must be non-items | ||
556 | // return expr now. | ||
557 | return MacroFileKind::Expr; | ||
558 | } | ||
559 | }; | ||
560 | |||
561 | match parent.kind() { | ||
562 | MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items, | ||
563 | LET_STMT => { | ||
564 | // FIXME: Handle Pattern | ||
565 | MacroFileKind::Expr | ||
566 | } | ||
567 | EXPR_STMT => MacroFileKind::Statements, | ||
568 | BLOCK => MacroFileKind::Statements, | ||
569 | ARG_LIST => MacroFileKind::Expr, | ||
570 | TRY_EXPR => MacroFileKind::Expr, | ||
571 | _ => { | ||
572 | // Unknown , Just guess it is `Items` | ||
573 | MacroFileKind::Items | ||
574 | } | ||
575 | } | ||
576 | } | ||
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 3c11c8a22..e1d93a8ef 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs | |||
@@ -151,6 +151,7 @@ pub(crate) fn parse_macro( | |||
151 | let fragment_kind = match macro_file.macro_file_kind { | 151 | let fragment_kind = match macro_file.macro_file_kind { |
152 | MacroFileKind::Items => FragmentKind::Items, | 152 | MacroFileKind::Items => FragmentKind::Items, |
153 | MacroFileKind::Expr => FragmentKind::Expr, | 153 | MacroFileKind::Expr => FragmentKind::Expr, |
154 | MacroFileKind::Statements => FragmentKind::Statements, | ||
154 | }; | 155 | }; |
155 | let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; | 156 | let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; |
156 | Some((parse, Arc::new(rev_token_map))) | 157 | Some((parse, Arc::new(rev_token_map))) |
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 1389f64ce..126d12fbb 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -109,6 +109,7 @@ pub struct MacroFile { | |||
109 | pub enum MacroFileKind { | 109 | pub enum MacroFileKind { |
110 | Items, | 110 | Items, |
111 | Expr, | 111 | Expr, |
112 | Statements, | ||
112 | } | 113 | } |
113 | 114 | ||
114 | /// `MacroCallId` identifies a particular macro invocation, like | 115 | /// `MacroCallId` identifies a particular macro invocation, like |
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 7f39262dc..7dbf33a16 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs | |||
@@ -84,24 +84,19 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { | |||
84 | }; | 84 | }; |
85 | 85 | ||
86 | res += &match token.kind() { | 86 | res += &match token.kind() { |
87 | k @ _ | 87 | k @ _ if is_text(k) && is_next(|it| !it.is_punct(), true) => { |
88 | if (k.is_keyword() || k.is_literal() || k == IDENT) | ||
89 | && is_next(|it| !it.is_punct(), true) => | ||
90 | { | ||
91 | token.text().to_string() + " " | 88 | token.text().to_string() + " " |
92 | } | 89 | } |
93 | L_CURLY if is_next(|it| it != R_CURLY, true) => { | 90 | L_CURLY if is_next(|it| it != R_CURLY, true) => { |
94 | indent += 1; | 91 | indent += 1; |
95 | format!(" {{\n{}", " ".repeat(indent)) | 92 | let leading_space = if is_last(|it| is_text(it), false) { " " } else { "" }; |
93 | format!("{}{{\n{}", leading_space, " ".repeat(indent)) | ||
96 | } | 94 | } |
97 | R_CURLY if is_last(|it| it != L_CURLY, true) => { | 95 | R_CURLY if is_last(|it| it != L_CURLY, true) => { |
98 | indent = indent.checked_sub(1).unwrap_or(0); | 96 | indent = indent.checked_sub(1).unwrap_or(0); |
99 | format!("\n}}{}", " ".repeat(indent)) | 97 | format!("\n{}}}", " ".repeat(indent)) |
100 | } | ||
101 | R_CURLY => { | ||
102 | indent = indent.checked_sub(1).unwrap_or(0); | ||
103 | format!("}}\n{}", " ".repeat(indent)) | ||
104 | } | 98 | } |
99 | R_CURLY => format!("}}\n{}", " ".repeat(indent)), | ||
105 | T![;] => format!(";\n{}", " ".repeat(indent)), | 100 | T![;] => format!(";\n{}", " ".repeat(indent)), |
106 | T![->] => " -> ".to_string(), | 101 | T![->] => " -> ".to_string(), |
107 | T![=] => " = ".to_string(), | 102 | T![=] => " = ".to_string(), |
@@ -112,7 +107,11 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { | |||
112 | last = Some(token.kind()); | 107 | last = Some(token.kind()); |
113 | } | 108 | } |
114 | 109 | ||
115 | res | 110 | return res; |
111 | |||
112 | fn is_text(k: SyntaxKind) -> bool { | ||
113 | k.is_keyword() || k.is_literal() || k == IDENT | ||
114 | } | ||
116 | } | 115 | } |
117 | 116 | ||
118 | #[cfg(test)] | 117 | #[cfg(test)] |
@@ -175,4 +174,47 @@ fn some_thing() -> u32 { | |||
175 | } | 174 | } |
176 | "###); | 175 | "###); |
177 | } | 176 | } |
177 | |||
178 | #[test] | ||
179 | fn macro_expand_match_ast() { | ||
180 | let res = check_expand_macro( | ||
181 | r#" | ||
182 | //- /lib.rs | ||
183 | macro_rules! match_ast { | ||
184 | (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; | ||
185 | |||
186 | (match ($node:expr) { | ||
187 | $( ast::$ast:ident($it:ident) => $res:block, )* | ||
188 | _ => $catch_all:expr $(,)? | ||
189 | }) => {{ | ||
190 | $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* | ||
191 | { $catch_all } | ||
192 | }}; | ||
193 | } | ||
194 | |||
195 | fn main() { | ||
196 | mat<|>ch_ast! { | ||
197 | match container { | ||
198 | ast::TraitDef(it) => {}, | ||
199 | ast::ImplBlock(it) => {}, | ||
200 | _ => { continue }, | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | "#, | ||
205 | ); | ||
206 | |||
207 | assert_eq!(res.name, "match_ast"); | ||
208 | assert_snapshot!(res.expansion, @r###" | ||
209 | { | ||
210 | if let Some(it) = ast::TraitDef::cast(container.clone()){} | ||
211 | else if let Some(it) = ast::ImplBlock::cast(container.clone()){} | ||
212 | else { | ||
213 | { | ||
214 | continue | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | "###); | ||
219 | } | ||
178 | } | 220 | } |