diff options
Diffstat (limited to 'crates/ide/src/expand_macro.rs')
-rw-r--r-- | crates/ide/src/expand_macro.rs | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index eebae5ebe..cc43c5772 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs | |||
@@ -2,10 +2,7 @@ use std::iter; | |||
2 | 2 | ||
3 | use hir::Semantics; | 3 | use hir::Semantics; |
4 | use ide_db::RootDatabase; | 4 | use ide_db::RootDatabase; |
5 | use syntax::{ | 5 | use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*, SyntaxNode, WalkEvent, T}; |
6 | algo::find_node_at_offset, ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*, | ||
7 | SyntaxNode, WalkEvent, T, | ||
8 | }; | ||
9 | 6 | ||
10 | use crate::FilePosition; | 7 | use crate::FilePosition; |
11 | 8 | ||
@@ -28,16 +25,33 @@ pub struct ExpandedMacro { | |||
28 | pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> { | 25 | pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> { |
29 | let sema = Semantics::new(db); | 26 | let sema = Semantics::new(db); |
30 | let file = sema.parse(position.file_id); | 27 | let file = sema.parse(position.file_id); |
31 | let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset)?; | ||
32 | let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; | ||
33 | 28 | ||
34 | let expanded = expand_macro_recur(&sema, &mac)?; | 29 | let tok = file.syntax().token_at_offset(position.offset).left_biased()?; |
30 | let mut expanded = None; | ||
31 | let mut name = None; | ||
32 | for node in tok.ancestors() { | ||
33 | if let Some(item) = ast::Item::cast(node.clone()) { | ||
34 | expanded = sema.expand_attr_macro(&item); | ||
35 | if expanded.is_some() { | ||
36 | // FIXME: add the macro name | ||
37 | // FIXME: make this recursive too | ||
38 | name = Some("?".to_string()); | ||
39 | break; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | if let Some(mac) = ast::MacroCall::cast(node) { | ||
44 | name = Some(mac.path()?.segment()?.name_ref()?.to_string()); | ||
45 | expanded = expand_macro_recur(&sema, &mac); | ||
46 | break; | ||
47 | } | ||
48 | } | ||
35 | 49 | ||
36 | // FIXME: | 50 | // FIXME: |
37 | // macro expansion may lose all white space information | 51 | // macro expansion may lose all white space information |
38 | // But we hope someday we can use ra_fmt for that | 52 | // But we hope someday we can use ra_fmt for that |
39 | let expansion = insert_whitespaces(expanded); | 53 | let expansion = insert_whitespaces(expanded?); |
40 | Some(ExpandedMacro { name: name_ref.text().to_string(), expansion }) | 54 | Some(ExpandedMacro { name: name?, expansion }) |
41 | } | 55 | } |
42 | 56 | ||
43 | fn expand_macro_recur( | 57 | fn expand_macro_recur( |