aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ids.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r--crates/ra_hir/src/ids.rs24
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..cf0566308 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -7,6 +7,7 @@ use std::{
7use ra_db::{LocationInterner, FileId}; 7use ra_db::{LocationInterner, FileId};
8use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast}; 8use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast};
9use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; 9use ra_arena::{Arena, RawId, ArenaId, impl_arena_id};
10use mbe::MacroRules;
10 11
11use crate::{ 12use 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 = macro_def_query(db, 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(&macro_arg).ok()?; 105 let tt = macro_rules.expand(&macro_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)]
128pub(crate) enum MacroDefId {
129 MacroByExample { source_item_id: SourceItemId },
130}
131
132fn 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)]
136pub struct MacroCallLoc { 150pub 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