diff options
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 18401f865..bac7b9e46 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -7,6 +7,7 @@ use std::{ | |||
7 | use ra_db::{LocationInterner, FileId}; | 7 | use ra_db::{LocationInterner, FileId}; |
8 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast}; | 8 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast}; |
9 | use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; | 9 | use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; |
10 | use mbe::MacroRules; | ||
10 | 11 | ||
11 | use crate::{ | 12 | use crate::{ |
12 | Module, | 13 | Module, |
@@ -100,10 +101,7 @@ fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<Tree | |||
100 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); | 101 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); |
101 | let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; | 102 | let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; |
102 | 103 | ||
103 | let def_map = db.crate_def_map(loc.module.krate); | 104 | let macro_rules = db.macro_def(loc.def)?; |
104 | let (krate, macro_id) = def_map.resolve_macro(macro_call_id)?; | ||
105 | let def_map = db.crate_def_map(krate); | ||
106 | let macro_rules = &def_map[macro_id]; | ||
107 | let tt = macro_rules.expand(¯o_arg).ok()?; | 105 | let tt = macro_rules.expand(¯o_arg).ok()?; |
108 | Some(mbe::token_tree_to_ast_item_list(&tt)) | 106 | Some(mbe::token_tree_to_ast_item_list(&tt)) |
109 | } | 107 | } |
@@ -126,6 +124,22 @@ impl From<MacroCallId> for HirFileId { | |||
126 | } | 124 | } |
127 | } | 125 | } |
128 | 126 | ||
127 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
128 | pub enum MacroDefId { | ||
129 | MacroByExample { source_item_id: SourceItemId }, | ||
130 | } | ||
131 | |||
132 | pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { | ||
133 | let syntax_node = match id { | ||
134 | MacroDefId::MacroByExample { source_item_id } => db.file_item(source_item_id), | ||
135 | }; | ||
136 | let macro_call = ast::MacroCall::cast(&syntax_node).unwrap(); | ||
137 | let arg = macro_call.token_tree()?; | ||
138 | let (tt, _) = mbe::ast_to_token_tree(arg)?; | ||
139 | let rules = MacroRules::parse(&tt).ok()?; | ||
140 | Some(Arc::new(rules)) | ||
141 | } | ||
142 | |||
129 | /// `MacroCallId` identifies a particular macro invocation, like | 143 | /// `MacroCallId` identifies a particular macro invocation, like |
130 | /// `println!("Hello, {}", world)`. | 144 | /// `println!("Hello, {}", world)`. |
131 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 145 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -134,7 +148,7 @@ impl_arena_id!(MacroCallId); | |||
134 | 148 | ||
135 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 149 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
136 | pub struct MacroCallLoc { | 150 | pub struct MacroCallLoc { |
137 | pub(crate) module: Module, | 151 | pub(crate) def: MacroDefId, |
138 | pub(crate) source_item_id: SourceItemId, | 152 | pub(crate) source_item_id: SourceItemId, |
139 | } | 153 | } |
140 | 154 | ||