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.rs25
1 files changed, 19 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index a144e4a1e..9596488d3 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -89,17 +89,31 @@ impl HirFileId {
89 ) -> TreeArc<SourceFile> { 89 ) -> TreeArc<SourceFile> {
90 match file_id.0 { 90 match file_id.0 {
91 HirFileIdRepr::File(file_id) => db.parse(file_id), 91 HirFileIdRepr::File(file_id) => db.parse(file_id),
92 HirFileIdRepr::Macro(m) => { 92 HirFileIdRepr::Macro(macro_call_id) => {
93 if let Some(exp) = db.expand_macro_invocation(m) {
94 return exp.file();
95 }
96 // returning an empty string looks fishy... 93 // returning an empty string looks fishy...
97 SourceFile::parse("") 94 parse_macro(db, macro_call_id).unwrap_or_else(|| SourceFile::parse(""))
98 } 95 }
99 } 96 }
100 } 97 }
101} 98}
102 99
100fn parse_macro(
101 db: &impl PersistentHirDatabase,
102 macro_call_id: MacroCallId,
103) -> Option<TreeArc<SourceFile>> {
104 let loc = macro_call_id.loc(db);
105 let syntax = db.file_item(loc.source_item_id);
106 let macro_call = ast::MacroCall::cast(&syntax).unwrap();
107 let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?;
108
109 let def_map = db.crate_def_map(loc.module.krate);
110 let (krate, macro_id) = def_map.resolve_macro(macro_call_id)?;
111 let def_map = db.crate_def_map(krate);
112 let macro_rules = &def_map[macro_id];
113 let tt = macro_rules.expand(&macro_arg).ok()?;
114 Some(mbe::token_tree_to_ast_item_list(&tt))
115}
116
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
104enum HirFileIdRepr { 118enum HirFileIdRepr {
105 File(FileId), 119 File(FileId),
@@ -373,7 +387,6 @@ impl SourceFileItems {
373impl std::ops::Index<SourceFileItemId> for SourceFileItems { 387impl std::ops::Index<SourceFileItemId> for SourceFileItems {
374 type Output = SyntaxNodePtr; 388 type Output = SyntaxNodePtr;
375 fn index(&self, idx: SourceFileItemId) -> &SyntaxNodePtr { 389 fn index(&self, idx: SourceFileItemId) -> &SyntaxNodePtr {
376 eprintln!("invalid SourceFileItemId({:?}) for file({:?})", idx, self.file_id);
377 &self.arena[idx] 390 &self.arena[idx]
378 } 391 }
379} 392}