diff options
Diffstat (limited to 'crates/ra_hir_def/src/nameres.rs')
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 83 |
1 files changed, 55 insertions, 28 deletions
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index c01e020ef..3b2e99647 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -47,8 +47,7 @@ | |||
47 | //! path and, upon success, we run macro expansion and "collect module" phase on | 47 | //! path and, upon success, we run macro expansion and "collect module" phase on |
48 | //! the result | 48 | //! the result |
49 | 49 | ||
50 | pub mod raw; | 50 | pub(crate) mod raw; |
51 | pub mod per_ns; | ||
52 | mod collector; | 51 | mod collector; |
53 | mod mod_resolution; | 52 | mod mod_resolution; |
54 | mod path_resolution; | 53 | mod path_resolution; |
@@ -58,7 +57,10 @@ mod tests; | |||
58 | 57 | ||
59 | use std::sync::Arc; | 58 | use std::sync::Arc; |
60 | 59 | ||
61 | use hir_expand::{ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, MacroDefId}; | 60 | use hir_expand::{ |
61 | ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId, | ||
62 | Source, | ||
63 | }; | ||
62 | use once_cell::sync::Lazy; | 64 | use once_cell::sync::Lazy; |
63 | use ra_arena::Arena; | 65 | use ra_arena::Arena; |
64 | use ra_db::{CrateId, Edition, FileId}; | 66 | use ra_db::{CrateId, Edition, FileId}; |
@@ -68,12 +70,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
68 | 70 | ||
69 | use crate::{ | 71 | use crate::{ |
70 | builtin_type::BuiltinType, | 72 | builtin_type::BuiltinType, |
71 | db::DefDatabase2, | 73 | db::DefDatabase, |
72 | nameres::{ | 74 | nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, |
73 | diagnostics::DefDiagnostic, path_resolution::ResolveMode, per_ns::PerNs, raw::ImportId, | ||
74 | }, | ||
75 | path::Path, | 75 | path::Path, |
76 | AstId, CrateModuleId, FunctionId, ImplId, ModuleDefId, ModuleId, TraitId, | 76 | per_ns::PerNs, |
77 | AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, | ||
77 | }; | 78 | }; |
78 | 79 | ||
79 | /// Contains all top-level defs from a macro-expanded crate | 80 | /// Contains all top-level defs from a macro-expanded crate |
@@ -86,8 +87,8 @@ pub struct CrateDefMap { | |||
86 | /// a dependency (`std` or `core`). | 87 | /// a dependency (`std` or `core`). |
87 | prelude: Option<ModuleId>, | 88 | prelude: Option<ModuleId>, |
88 | extern_prelude: FxHashMap<Name, ModuleDefId>, | 89 | extern_prelude: FxHashMap<Name, ModuleDefId>, |
89 | root: CrateModuleId, | 90 | root: LocalModuleId, |
90 | modules: Arena<CrateModuleId, ModuleData>, | 91 | modules: Arena<LocalModuleId, ModuleData>, |
91 | 92 | ||
92 | /// Some macros are not well-behavior, which leads to infinite loop | 93 | /// Some macros are not well-behavior, which leads to infinite loop |
93 | /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } } | 94 | /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } } |
@@ -104,24 +105,27 @@ pub struct CrateDefMap { | |||
104 | diagnostics: Vec<DefDiagnostic>, | 105 | diagnostics: Vec<DefDiagnostic>, |
105 | } | 106 | } |
106 | 107 | ||
107 | impl std::ops::Index<CrateModuleId> for CrateDefMap { | 108 | impl std::ops::Index<LocalModuleId> for CrateDefMap { |
108 | type Output = ModuleData; | 109 | type Output = ModuleData; |
109 | fn index(&self, id: CrateModuleId) -> &ModuleData { | 110 | fn index(&self, id: LocalModuleId) -> &ModuleData { |
110 | &self.modules[id] | 111 | &self.modules[id] |
111 | } | 112 | } |
112 | } | 113 | } |
113 | 114 | ||
114 | #[derive(Default, Debug, PartialEq, Eq)] | 115 | #[derive(Default, Debug, PartialEq, Eq)] |
115 | pub struct ModuleData { | 116 | pub struct ModuleData { |
116 | pub parent: Option<CrateModuleId>, | 117 | pub parent: Option<LocalModuleId>, |
117 | pub children: FxHashMap<Name, CrateModuleId>, | 118 | pub children: FxHashMap<Name, LocalModuleId>, |
118 | pub scope: ModuleScope, | 119 | pub scope: ModuleScope, |
120 | |||
121 | // FIXME: these can't be both null, we need a three-state enum here. | ||
119 | /// None for root | 122 | /// None for root |
120 | pub declaration: Option<AstId<ast::Module>>, | 123 | pub declaration: Option<AstId<ast::Module>>, |
121 | /// None for inline modules. | 124 | /// None for inline modules. |
122 | /// | 125 | /// |
123 | /// Note that non-inline modules, by definition, live inside non-macro file. | 126 | /// Note that non-inline modules, by definition, live inside non-macro file. |
124 | pub definition: Option<FileId>, | 127 | pub definition: Option<FileId>, |
128 | |||
125 | pub impls: Vec<ImplId>, | 129 | pub impls: Vec<ImplId>, |
126 | } | 130 | } |
127 | 131 | ||
@@ -207,21 +211,21 @@ pub struct Resolution { | |||
207 | /// None for unresolved | 211 | /// None for unresolved |
208 | pub def: PerNs, | 212 | pub def: PerNs, |
209 | /// ident by which this is imported into local scope. | 213 | /// ident by which this is imported into local scope. |
210 | pub import: Option<ImportId>, | 214 | pub import: Option<LocalImportId>, |
211 | } | 215 | } |
212 | 216 | ||
213 | impl CrateDefMap { | 217 | impl CrateDefMap { |
214 | pub(crate) fn crate_def_map_query( | 218 | pub(crate) fn crate_def_map_query( |
215 | // Note that this doesn't have `+ AstDatabase`! | 219 | // Note that this doesn't have `+ AstDatabase`! |
216 | // This gurantess that `CrateDefMap` is stable across reparses. | 220 | // This gurantess that `CrateDefMap` is stable across reparses. |
217 | db: &impl DefDatabase2, | 221 | db: &impl DefDatabase, |
218 | krate: CrateId, | 222 | krate: CrateId, |
219 | ) -> Arc<CrateDefMap> { | 223 | ) -> Arc<CrateDefMap> { |
220 | let _p = profile("crate_def_map_query"); | 224 | let _p = profile("crate_def_map_query"); |
221 | let def_map = { | 225 | let def_map = { |
222 | let crate_graph = db.crate_graph(); | 226 | let crate_graph = db.crate_graph(); |
223 | let edition = crate_graph.edition(krate); | 227 | let edition = crate_graph.edition(krate); |
224 | let mut modules: Arena<CrateModuleId, ModuleData> = Arena::default(); | 228 | let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default(); |
225 | let root = modules.alloc(ModuleData::default()); | 229 | let root = modules.alloc(ModuleData::default()); |
226 | CrateDefMap { | 230 | CrateDefMap { |
227 | krate, | 231 | krate, |
@@ -242,7 +246,7 @@ impl CrateDefMap { | |||
242 | self.krate | 246 | self.krate |
243 | } | 247 | } |
244 | 248 | ||
245 | pub fn root(&self) -> CrateModuleId { | 249 | pub fn root(&self) -> LocalModuleId { |
246 | self.root | 250 | self.root |
247 | } | 251 | } |
248 | 252 | ||
@@ -256,8 +260,8 @@ impl CrateDefMap { | |||
256 | 260 | ||
257 | pub fn add_diagnostics( | 261 | pub fn add_diagnostics( |
258 | &self, | 262 | &self, |
259 | db: &impl DefDatabase2, | 263 | db: &impl DefDatabase, |
260 | module: CrateModuleId, | 264 | module: LocalModuleId, |
261 | sink: &mut DiagnosticSink, | 265 | sink: &mut DiagnosticSink, |
262 | ) { | 266 | ) { |
263 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) | 267 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) |
@@ -265,19 +269,19 @@ impl CrateDefMap { | |||
265 | 269 | ||
266 | pub fn resolve_path( | 270 | pub fn resolve_path( |
267 | &self, | 271 | &self, |
268 | db: &impl DefDatabase2, | 272 | db: &impl DefDatabase, |
269 | original_module: CrateModuleId, | 273 | original_module: LocalModuleId, |
270 | path: &Path, | 274 | path: &Path, |
271 | ) -> (PerNs, Option<usize>) { | 275 | ) -> (PerNs, Option<usize>) { |
272 | let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); | 276 | let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); |
273 | (res.resolved_def, res.segment_index) | 277 | (res.resolved_def, res.segment_index) |
274 | } | 278 | } |
275 | 279 | ||
276 | pub fn modules(&self) -> impl Iterator<Item = CrateModuleId> + '_ { | 280 | pub fn modules(&self) -> impl Iterator<Item = LocalModuleId> + '_ { |
277 | self.modules.iter().map(|(id, _data)| id) | 281 | self.modules.iter().map(|(id, _data)| id) |
278 | } | 282 | } |
279 | 283 | ||
280 | pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = CrateModuleId> + '_ { | 284 | pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ { |
281 | self.modules | 285 | self.modules |
282 | .iter() | 286 | .iter() |
283 | .filter(move |(_id, data)| data.definition == Some(file_id)) | 287 | .filter(move |(_id, data)| data.definition == Some(file_id)) |
@@ -285,17 +289,40 @@ impl CrateDefMap { | |||
285 | } | 289 | } |
286 | } | 290 | } |
287 | 291 | ||
292 | impl ModuleData { | ||
293 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | ||
294 | pub fn definition_source( | ||
295 | &self, | ||
296 | db: &impl DefDatabase, | ||
297 | ) -> Source<Either<ast::SourceFile, ast::Module>> { | ||
298 | if let Some(file_id) = self.definition { | ||
299 | let sf = db.parse(file_id).tree(); | ||
300 | return Source::new(file_id.into(), Either::A(sf)); | ||
301 | } | ||
302 | let decl = self.declaration.unwrap(); | ||
303 | Source::new(decl.file_id(), Either::B(decl.to_node(db))) | ||
304 | } | ||
305 | |||
306 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | ||
307 | /// `None` for the crate root. | ||
308 | pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { | ||
309 | let decl = self.declaration?; | ||
310 | let value = decl.to_node(db); | ||
311 | Some(Source { file_id: decl.file_id(), value }) | ||
312 | } | ||
313 | } | ||
314 | |||
288 | mod diagnostics { | 315 | mod diagnostics { |
289 | use hir_expand::diagnostics::DiagnosticSink; | 316 | use hir_expand::diagnostics::DiagnosticSink; |
290 | use ra_db::RelativePathBuf; | 317 | use ra_db::RelativePathBuf; |
291 | use ra_syntax::{ast, AstPtr}; | 318 | use ra_syntax::{ast, AstPtr}; |
292 | 319 | ||
293 | use crate::{db::DefDatabase2, diagnostics::UnresolvedModule, nameres::CrateModuleId, AstId}; | 320 | use crate::{db::DefDatabase, diagnostics::UnresolvedModule, nameres::LocalModuleId, AstId}; |
294 | 321 | ||
295 | #[derive(Debug, PartialEq, Eq)] | 322 | #[derive(Debug, PartialEq, Eq)] |
296 | pub(super) enum DefDiagnostic { | 323 | pub(super) enum DefDiagnostic { |
297 | UnresolvedModule { | 324 | UnresolvedModule { |
298 | module: CrateModuleId, | 325 | module: LocalModuleId, |
299 | declaration: AstId<ast::Module>, | 326 | declaration: AstId<ast::Module>, |
300 | candidate: RelativePathBuf, | 327 | candidate: RelativePathBuf, |
301 | }, | 328 | }, |
@@ -304,8 +331,8 @@ mod diagnostics { | |||
304 | impl DefDiagnostic { | 331 | impl DefDiagnostic { |
305 | pub(super) fn add_to( | 332 | pub(super) fn add_to( |
306 | &self, | 333 | &self, |
307 | db: &impl DefDatabase2, | 334 | db: &impl DefDatabase, |
308 | target_module: CrateModuleId, | 335 | target_module: LocalModuleId, |
309 | sink: &mut DiagnosticSink, | 336 | sink: &mut DiagnosticSink, |
310 | ) { | 337 | ) { |
311 | match self { | 338 | match self { |