diff options
author | Aleksey Kladov <[email protected]> | 2019-03-26 15:03:17 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-03-26 15:03:17 +0000 |
commit | 071a19537d4399fd04d1e9594ab7878502a12d21 (patch) | |
tree | b6cdd380b2af4f570ebc6e831ef3ebaa5c4e9adc | |
parent | fb8b354dcc837d5eb9b81fc205e4282a203df177 (diff) |
strongy-typed ids for macros
-rw-r--r-- | crates/ra_hir/src/ids.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/source_id.rs | 4 |
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}; | |||
10 | use mbe::MacroRules; | 10 | use mbe::MacroRules; |
11 | 11 | ||
12 | use crate::{ | 12 | use 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 | ||
97 | fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> { | 97 | fn 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)] |
127 | pub enum MacroDefId { | 126 | pub struct MacroDefId(pub(crate) AstId<ast::MacroCall>); |
128 | MacroByExample { source_item_id: SourceItemId }, | ||
129 | } | ||
130 | 127 | ||
131 | pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { | 128 | pub(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)] |
149 | pub struct MacroCallLoc { | 143 | pub 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 | ||
154 | impl MacroCallId { | 148 | impl 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 | ||
8 | use crate::{ | 8 | use 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(¯o_id) = | 468 | if let Some(¯o_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)] |
162 | pub(super) struct MacroData { | 162 | pub(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 | ||
6 | use crate::{HirFileId, DefDatabase}; | 6 | use crate::{HirFileId, DefDatabase}; |
7 | 7 | ||
8 | #[derive(Debug, PartialEq, Eq)] | 8 | #[derive(Debug, PartialEq, Eq, Hash)] |
9 | pub(crate) struct AstId<N: AstNode> { | 9 | pub(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)] |
34 | pub(crate) struct FileAstId<N: AstNode> { | 34 | pub(crate) struct FileAstId<N: AstNode> { |
35 | raw: SourceFileItemId, | 35 | raw: SourceFileItemId, |
36 | _ty: PhantomData<N>, | 36 | _ty: PhantomData<N>, |