aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/macros.rs38
-rw-r--r--crates/ra_hir/src/macros/tt.rs12
2 files changed, 43 insertions, 7 deletions
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs
index 647df4260..9ba381685 100644
--- a/crates/ra_hir/src/macros.rs
+++ b/crates/ra_hir/src/macros.rs
@@ -16,6 +16,7 @@ use std::sync::Arc;
16 16
17use ra_syntax::{ 17use ra_syntax::{
18 TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr, 18 TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr,
19 SyntaxKind::*,
19 ast::{self, NameOwner}, 20 ast::{self, NameOwner},
20}; 21};
21 22
@@ -201,6 +202,39 @@ pub(crate) fn expand_macro_invocation(
201 def.expand(input).map(Arc::new) 202 def.expand(input).map(Arc::new)
202} 203}
203 204
204fn macro_call_to_tt(call: &ast::MacroCall) -> Option<tt::TokenTree> { 205fn macro_call_to_tt(call: &ast::MacroCall) -> Option<tt::Subtree> {
205 None 206 let tt = call.token_tree()?;
207 convert_tt(tt.syntax())
208}
209
210fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> {
211 let first_child = tt.first_child()?;
212 let last_child = tt.last_child()?;
213 let delimiter = match (first_child.kind(), last_child.kind()) {
214 (L_PAREN, R_PAREN) => tt::Delimiter::Parenthesis,
215 (L_CURLY, R_CURLY) => tt::Delimiter::Brace,
216 (L_BRACK, R_BRACK) => tt::Delimiter::Bracket,
217 _ => return None,
218 };
219 let mut token_trees = Vec::new();
220 for child in tt.children().skip(1) {
221 if child == first_child || child == last_child || child.kind().is_trivia() {
222 continue;
223 }
224 let child = if child.kind() == TOKEN_TREE {
225 convert_tt(child)?.into()
226 } else if child.kind().is_keyword() {
227 let text = child.leaf_text().unwrap().clone();
228 tt::Leaf::from(tt::Ident { text }).into()
229 } else {
230 return None;
231 };
232 token_trees.push(child)
233 }
234
235 let res = tt::Subtree {
236 delimiter,
237 token_trees,
238 };
239 Some(res)
206} 240}
diff --git a/crates/ra_hir/src/macros/tt.rs b/crates/ra_hir/src/macros/tt.rs
index 817cb262e..11b1089d3 100644
--- a/crates/ra_hir/src/macros/tt.rs
+++ b/crates/ra_hir/src/macros/tt.rs
@@ -4,16 +4,18 @@ pub(crate) enum TokenTree {
4 Leaf(Leaf), 4 Leaf(Leaf),
5 Subtree(Subtree), 5 Subtree(Subtree),
6} 6}
7impl_froms!(TokenTree: Leaf, Subtree);
7 8
8pub(crate) enum Leaf { 9pub(crate) enum Leaf {
9 Literal(Literal), 10 Literal(Literal),
10 Punct(Punct), 11 Punct(Punct),
11 Ident(Ident), 12 Ident(Ident),
12} 13}
14impl_froms!(Leaf: Literal, Punct, Ident);
13 15
14pub(crate) struct Subtree { 16pub(crate) struct Subtree {
15 delimiter: Delimiter, 17 pub(crate) delimiter: Delimiter,
16 token_trees: Vec<TokenTree>, 18 pub(crate) token_trees: Vec<TokenTree>,
17} 19}
18 20
19pub(crate) enum Delimiter { 21pub(crate) enum Delimiter {
@@ -24,13 +26,13 @@ pub(crate) enum Delimiter {
24} 26}
25 27
26pub(crate) struct Literal { 28pub(crate) struct Literal {
27 text: SmolStr, 29 pub(crate) text: SmolStr,
28} 30}
29 31
30pub(crate) struct Punct { 32pub(crate) struct Punct {
31 char: char, 33 pub(crate) char: char,
32} 34}
33 35
34pub(crate) struct Ident { 36pub(crate) struct Ident {
35 text: SmolStr, 37 pub(crate) text: SmolStr,
36} 38}