diff options
Diffstat (limited to 'crates/hir_def/src/nameres.rs')
-rw-r--r-- | crates/hir_def/src/nameres.rs | 73 |
1 files changed, 26 insertions, 47 deletions
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 4fbbecb38..199771e9a 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs | |||
@@ -62,7 +62,7 @@ use la_arena::Arena; | |||
62 | use profile::Count; | 62 | use profile::Count; |
63 | use rustc_hash::FxHashMap; | 63 | use rustc_hash::FxHashMap; |
64 | use stdx::format_to; | 64 | use stdx::format_to; |
65 | use syntax::{ast, AstNode}; | 65 | use syntax::ast; |
66 | 66 | ||
67 | use crate::{ | 67 | use crate::{ |
68 | db::DefDatabase, | 68 | db::DefDatabase, |
@@ -70,14 +70,14 @@ use crate::{ | |||
70 | nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, | 70 | nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, |
71 | path::ModPath, | 71 | path::ModPath, |
72 | per_ns::PerNs, | 72 | per_ns::PerNs, |
73 | AstId, LocalModuleId, ModuleDefId, ModuleId, | 73 | AstId, BlockId, BlockLoc, LocalModuleId, ModuleDefId, ModuleId, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | /// Contains all top-level defs from a macro-expanded crate | 76 | /// Contains all top-level defs from a macro-expanded crate |
77 | #[derive(Debug, PartialEq, Eq)] | 77 | #[derive(Debug, PartialEq, Eq)] |
78 | pub struct DefMap { | 78 | pub struct DefMap { |
79 | _c: Count<Self>, | 79 | _c: Count<Self>, |
80 | parent: Option<Arc<DefMap>>, | 80 | block: Option<BlockInfo>, |
81 | root: LocalModuleId, | 81 | root: LocalModuleId, |
82 | modules: Arena<ModuleData>, | 82 | modules: Arena<ModuleData>, |
83 | krate: CrateId, | 83 | krate: CrateId, |
@@ -91,6 +91,13 @@ pub struct DefMap { | |||
91 | diagnostics: Vec<DefDiagnostic>, | 91 | diagnostics: Vec<DefDiagnostic>, |
92 | } | 92 | } |
93 | 93 | ||
94 | #[derive(Debug, PartialEq, Eq)] | ||
95 | struct BlockInfo { | ||
96 | block: BlockId, | ||
97 | parent: Arc<DefMap>, | ||
98 | parent_module: LocalModuleId, | ||
99 | } | ||
100 | |||
94 | impl std::ops::Index<LocalModuleId> for DefMap { | 101 | impl std::ops::Index<LocalModuleId> for DefMap { |
95 | type Output = ModuleData; | 102 | type Output = ModuleData; |
96 | fn index(&self, id: LocalModuleId) -> &ModuleData { | 103 | fn index(&self, id: LocalModuleId) -> &ModuleData { |
@@ -190,15 +197,12 @@ impl DefMap { | |||
190 | Arc::new(def_map) | 197 | Arc::new(def_map) |
191 | } | 198 | } |
192 | 199 | ||
193 | pub(crate) fn block_def_map_query( | 200 | pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> { |
194 | db: &dyn DefDatabase, | 201 | let block: BlockLoc = db.lookup_intern_block(block_id); |
195 | krate: CrateId, | 202 | let item_tree = db.item_tree(block.ast_id.file_id); |
196 | block: AstId<ast::BlockExpr>, | 203 | let block_items = item_tree.inner_items_of_block(block.ast_id.value); |
197 | ) -> Arc<DefMap> { | ||
198 | let item_tree = db.item_tree(block.file_id); | ||
199 | let block_items = item_tree.inner_items_of_block(block.value); | ||
200 | 204 | ||
201 | let parent = parent_def_map(db, krate, block); | 205 | let parent = block.module.def_map(db); |
202 | 206 | ||
203 | if block_items.is_empty() { | 207 | if block_items.is_empty() { |
204 | // If there are no inner items, nothing new is brought into scope, so we can just return | 208 | // If there are no inner items, nothing new is brought into scope, so we can just return |
@@ -206,10 +210,13 @@ impl DefMap { | |||
206 | return parent; | 210 | return parent; |
207 | } | 211 | } |
208 | 212 | ||
209 | let mut def_map = DefMap::empty(krate, parent.edition); | 213 | let block_info = |
210 | def_map.parent = Some(parent); | 214 | BlockInfo { block: block_id, parent, parent_module: block.module.local_id }; |
215 | |||
216 | let mut def_map = DefMap::empty(block.module.krate, block_info.parent.edition); | ||
217 | def_map.block = Some(block_info); | ||
211 | 218 | ||
212 | let def_map = collector::collect_defs(db, def_map, Some(block.value)); | 219 | let def_map = collector::collect_defs(db, def_map, Some(block.ast_id.value)); |
213 | Arc::new(def_map) | 220 | Arc::new(def_map) |
214 | } | 221 | } |
215 | 222 | ||
@@ -218,7 +225,7 @@ impl DefMap { | |||
218 | let root = modules.alloc(ModuleData::default()); | 225 | let root = modules.alloc(ModuleData::default()); |
219 | DefMap { | 226 | DefMap { |
220 | _c: Count::new(), | 227 | _c: Count::new(), |
221 | parent: None, | 228 | block: None, |
222 | krate, | 229 | krate, |
223 | edition, | 230 | edition, |
224 | extern_prelude: FxHashMap::default(), | 231 | extern_prelude: FxHashMap::default(), |
@@ -266,7 +273,8 @@ impl DefMap { | |||
266 | } | 273 | } |
267 | 274 | ||
268 | pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { | 275 | pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { |
269 | ModuleId { krate: self.krate, local_id } | 276 | let block = self.block.as_ref().map(|b| b.block); |
277 | ModuleId { krate: self.krate, local_id, block } | ||
270 | } | 278 | } |
271 | 279 | ||
272 | pub(crate) fn resolve_path( | 280 | pub(crate) fn resolve_path( |
@@ -286,9 +294,9 @@ impl DefMap { | |||
286 | pub fn dump(&self) -> String { | 294 | pub fn dump(&self) -> String { |
287 | let mut buf = String::new(); | 295 | let mut buf = String::new(); |
288 | let mut current_map = self; | 296 | let mut current_map = self; |
289 | while let Some(parent) = ¤t_map.parent { | 297 | while let Some(block) = ¤t_map.block { |
290 | go(&mut buf, current_map, "block scope", current_map.root); | 298 | go(&mut buf, current_map, "block scope", current_map.root); |
291 | current_map = &**parent; | 299 | current_map = &*block.parent; |
292 | } | 300 | } |
293 | go(&mut buf, current_map, "crate", current_map.root); | 301 | go(&mut buf, current_map, "crate", current_map.root); |
294 | return buf; | 302 | return buf; |
@@ -342,35 +350,6 @@ impl ModuleData { | |||
342 | } | 350 | } |
343 | } | 351 | } |
344 | 352 | ||
345 | fn parent_def_map( | ||
346 | db: &dyn DefDatabase, | ||
347 | krate: CrateId, | ||
348 | block: AstId<ast::BlockExpr>, | ||
349 | ) -> Arc<DefMap> { | ||
350 | // FIXME: store this info in the item tree instead of reparsing here | ||
351 | let ast_id_map = db.ast_id_map(block.file_id); | ||
352 | let block_ptr = ast_id_map.get(block.value); | ||
353 | let root = match db.parse_or_expand(block.file_id) { | ||
354 | Some(it) => it, | ||
355 | None => { | ||
356 | return Arc::new(DefMap::empty(krate, Edition::Edition2018)); | ||
357 | } | ||
358 | }; | ||
359 | let ast = block_ptr.to_node(&root); | ||
360 | |||
361 | for ancestor in ast.syntax().ancestors().skip(1) { | ||
362 | if let Some(block_expr) = ast::BlockExpr::cast(ancestor) { | ||
363 | let ancestor_id = ast_id_map.ast_id(&block_expr); | ||
364 | let ast_id = InFile::new(block.file_id, ancestor_id); | ||
365 | let parent_map = db.block_def_map(krate, ast_id); | ||
366 | return parent_map; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | // No enclosing block scope, so the parent is the crate-level DefMap. | ||
371 | db.crate_def_map(krate) | ||
372 | } | ||
373 | |||
374 | #[derive(Debug, Clone, PartialEq, Eq)] | 353 | #[derive(Debug, Clone, PartialEq, Eq)] |
375 | pub enum ModuleSource { | 354 | pub enum ModuleSource { |
376 | SourceFile(ast::SourceFile), | 355 | SourceFile(ast::SourceFile), |