aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-03-26 15:03:17 +0000
committerAleksey Kladov <[email protected]>2019-03-26 15:03:17 +0000
commit071a19537d4399fd04d1e9594ab7878502a12d21 (patch)
treeb6cdd380b2af4f570ebc6e831ef3ebaa5c4e9adc
parentfb8b354dcc837d5eb9b81fc205e4282a203df177 (diff)
strongy-typed ids for macros
-rw-r--r--crates/ra_hir/src/ids.rs18
-rw-r--r--crates/ra_hir/src/nameres/collector.rs24
-rw-r--r--crates/ra_hir/src/nameres/raw.rs6
-rw-r--r--crates/ra_hir/src/source_id.rs4
4 files changed, 19 insertions, 33 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index e73dd5d21..b503e0ee5 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -10,7 +10,7 @@ use ra_arena::{RawId, ArenaId, impl_arena_id};
10use mbe::MacroRules; 10use mbe::MacroRules;
11 11
12use crate::{ 12use crate::{
13 Module, DefDatabase, SourceItemId, SourceFileItemId, 13 Module, DefDatabase, SourceItemId, SourceFileItemId, AstId,
14}; 14};
15 15
16#[derive(Debug, Default)] 16#[derive(Debug, Default)]
@@ -68,7 +68,7 @@ impl HirFileId {
68 HirFileIdRepr::File(file_id) => file_id, 68 HirFileIdRepr::File(file_id) => file_id,
69 HirFileIdRepr::Macro(macro_call_id) => { 69 HirFileIdRepr::Macro(macro_call_id) => {
70 let loc = macro_call_id.loc(db); 70 let loc = macro_call_id.loc(db);
71 loc.source_item_id.file_id.original_file(db) 71 loc.ast_id.file_id().original_file(db)
72 } 72 }
73 } 73 }
74 } 74 }
@@ -96,8 +96,7 @@ impl HirFileId {
96 96
97fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> { 97fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> {
98 let loc = macro_call_id.loc(db); 98 let loc = macro_call_id.loc(db);
99 let syntax = db.file_item(loc.source_item_id); 99 let macro_call = loc.ast_id.to_node(db);
100 let macro_call = ast::MacroCall::cast(&syntax).unwrap();
101 let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; 100 let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?;
102 101
103 let macro_rules = db.macro_def(loc.def)?; 102 let macro_rules = db.macro_def(loc.def)?;
@@ -124,15 +123,10 @@ impl From<MacroCallId> for HirFileId {
124} 123}
125 124
126#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 125#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
127pub enum MacroDefId { 126pub struct MacroDefId(pub(crate) AstId<ast::MacroCall>);
128 MacroByExample { source_item_id: SourceItemId },
129}
130 127
131pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { 128pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> {
132 let syntax_node = match id { 129 let macro_call = id.0.to_node(db);
133 MacroDefId::MacroByExample { source_item_id } => db.file_item(source_item_id),
134 };
135 let macro_call = ast::MacroCall::cast(&syntax_node).unwrap();
136 let arg = macro_call.token_tree()?; 130 let arg = macro_call.token_tree()?;
137 let (tt, _) = mbe::ast_to_token_tree(arg)?; 131 let (tt, _) = mbe::ast_to_token_tree(arg)?;
138 let rules = MacroRules::parse(&tt).ok()?; 132 let rules = MacroRules::parse(&tt).ok()?;
@@ -148,7 +142,7 @@ impl_arena_id!(MacroCallId);
148#[derive(Debug, Clone, PartialEq, Eq, Hash)] 142#[derive(Debug, Clone, PartialEq, Eq, Hash)]
149pub struct MacroCallLoc { 143pub struct MacroCallLoc {
150 pub(crate) def: MacroDefId, 144 pub(crate) def: MacroDefId,
151 pub(crate) source_item_id: SourceItemId, 145 pub(crate) ast_id: AstId<ast::MacroCall>,
152} 146}
153 147
154impl MacroCallId { 148impl MacroCallId {
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index e6fd8632a..b5f02ab80 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -7,7 +7,7 @@ use ra_syntax::ast;
7 7
8use crate::{ 8use crate::{
9 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, 9 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
10 DefDatabase, HirFileId, Name, Path, SourceItemId, 10 DefDatabase, HirFileId, Name, Path,
11 KnownName, 11 KnownName,
12 nameres::{ 12 nameres::{
13 Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, 13 Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode,
@@ -53,7 +53,7 @@ struct DefCollector<DB> {
53 def_map: CrateDefMap, 53 def_map: CrateDefMap,
54 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, 54 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
55 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, 55 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
56 unexpanded_macros: Vec<(CrateModuleId, SourceItemId, Path)>, 56 unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>,
57 global_macro_scope: FxHashMap<Name, MacroDefId>, 57 global_macro_scope: FxHashMap<Name, MacroDefId>,
58} 58}
59 59
@@ -295,7 +295,7 @@ where
295 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); 295 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
296 let mut resolved = Vec::new(); 296 let mut resolved = Vec::new();
297 let mut res = ReachedFixedPoint::Yes; 297 let mut res = ReachedFixedPoint::Yes;
298 macros.retain(|(module_id, source_item_id, path)| { 298 macros.retain(|(module_id, ast_id, path)| {
299 if path.segments.len() != 2 { 299 if path.segments.len() != 2 {
300 return true; 300 return true;
301 } 301 }
@@ -311,8 +311,7 @@ where
311 res = ReachedFixedPoint::No; 311 res = ReachedFixedPoint::No;
312 let def_map = self.db.crate_def_map(krate); 312 let def_map = self.db.crate_def_map(krate);
313 if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { 313 if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() {
314 let call_id = 314 let call_id = MacroCallLoc { def: macro_id, ast_id: *ast_id }.id(self.db);
315 MacroCallLoc { def: macro_id, source_item_id: *source_item_id }.id(self.db);
316 resolved.push((*module_id, call_id)); 315 resolved.push((*module_id, call_id));
317 } 316 }
318 false 317 false
@@ -456,34 +455,27 @@ where
456 // Case 1: macro rules, define a macro in crate-global mutable scope 455 // Case 1: macro rules, define a macro in crate-global mutable scope
457 if is_macro_rules(&mac.path) { 456 if is_macro_rules(&mac.path) {
458 if let Some(name) = &mac.name { 457 if let Some(name) = &mac.name {
459 let macro_id = MacroDefId::MacroByExample { 458 let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id));
460 source_item_id: mac.source_item_id.with_file_id(self.file_id),
461 };
462 self.def_collector.define_macro(name.clone(), macro_id, mac.export) 459 self.def_collector.define_macro(name.clone(), macro_id, mac.export)
463 } 460 }
464 return; 461 return;
465 } 462 }
466 463
467 let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id }; 464 let ast_id = mac.ast_id.with_file_id(self.file_id);
468 465
469 // Case 2: try to expand macro_rules from this crate, triggering 466 // Case 2: try to expand macro_rules from this crate, triggering
470 // recursive item collection. 467 // recursive item collection.
471 if let Some(&macro_id) = 468 if let Some(&macro_id) =
472 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) 469 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name))
473 { 470 {
474 let macro_call_id = 471 let macro_call_id = MacroCallLoc { def: macro_id, ast_id }.id(self.def_collector.db);
475 MacroCallLoc { def: macro_id, source_item_id }.id(self.def_collector.db);
476 472
477 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id); 473 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id);
478 return; 474 return;
479 } 475 }
480 476
481 // Case 3: path to a macro from another crate, expand during name resolution 477 // Case 3: path to a macro from another crate, expand during name resolution
482 self.def_collector.unexpanded_macros.push(( 478 self.def_collector.unexpanded_macros.push((self.module_id, ast_id, mac.path.clone()))
483 self.module_id,
484 source_item_id,
485 mac.path.clone(),
486 ))
487 } 479 }
488} 480}
489 481
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 09acd5a98..684bd1d50 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -160,7 +160,7 @@ impl_arena_id!(Macro);
160 160
161#[derive(Debug, PartialEq, Eq)] 161#[derive(Debug, PartialEq, Eq)]
162pub(super) struct MacroData { 162pub(super) struct MacroData {
163 pub(super) source_item_id: SourceFileItemId, 163 pub(super) ast_id: FileAstId<ast::MacroCall>,
164 pub(super) path: Path, 164 pub(super) path: Path,
165 pub(super) name: Option<Name>, 165 pub(super) name: Option<Name>,
166 pub(super) export: bool, 166 pub(super) export: bool,
@@ -285,9 +285,9 @@ impl RawItemsCollector {
285 }; 285 };
286 286
287 let name = m.name().map(|it| it.as_name()); 287 let name = m.name().map(|it| it.as_name());
288 let source_item_id = self.source_file_items.id_of_unchecked(m.syntax()); 288 let ast_id = self.source_file_items.ast_id(m);
289 let export = m.has_atom_attr("macro_export"); 289 let export = m.has_atom_attr("macro_export");
290 let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, name, export }); 290 let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
291 self.push_item(current_module, RawItem::Macro(m)); 291 self.push_item(current_module, RawItem::Macro(m));
292 } 292 }
293 293
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs
index 881cc590e..1dadd76c5 100644
--- a/crates/ra_hir/src/source_id.rs
+++ b/crates/ra_hir/src/source_id.rs
@@ -5,7 +5,7 @@ use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast};
5 5
6use crate::{HirFileId, DefDatabase}; 6use crate::{HirFileId, DefDatabase};
7 7
8#[derive(Debug, PartialEq, Eq)] 8#[derive(Debug, PartialEq, Eq, Hash)]
9pub(crate) struct AstId<N: AstNode> { 9pub(crate) struct AstId<N: AstNode> {
10 file_id: HirFileId, 10 file_id: HirFileId,
11 file_ast_id: FileAstId<N>, 11 file_ast_id: FileAstId<N>,
@@ -30,7 +30,7 @@ impl<N: AstNode> AstId<N> {
30 } 30 }
31} 31}
32 32
33#[derive(Debug, PartialEq, Eq)] 33#[derive(Debug, PartialEq, Eq, Hash)]
34pub(crate) struct FileAstId<N: AstNode> { 34pub(crate) struct FileAstId<N: AstNode> {
35 raw: SourceFileItemId, 35 raw: SourceFileItemId,
36 _ty: PhantomData<N>, 36 _ty: PhantomData<N>,