diff options
author | Sergey Parilin <[email protected]> | 2019-04-02 15:55:14 +0100 |
---|---|---|
committer | Sergey Parilin <[email protected]> | 2019-04-02 15:55:14 +0100 |
commit | b74449e9952846a8ea66c3507e52c24348d6dbc9 (patch) | |
tree | 00bb1101334b0bf1b189a2e6451cb28e0af959a1 /crates/ra_hir/src/nameres.rs | |
parent | 9b73f809596e955216dde24fcf921d6985a1a767 (diff) | |
parent | 849d7428aa6b733d452b2ebc55ec322d96345f49 (diff) |
Merge remote-tracking branch 'upstream/master' into issue961_profiling
Diffstat (limited to 'crates/ra_hir/src/nameres.rs')
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 115 |
1 files changed, 67 insertions, 48 deletions
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 5ac878c79..8adc6d368 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -59,12 +59,16 @@ use rustc_hash::FxHashMap; | |||
59 | use ra_arena::{Arena, RawId, impl_arena_id}; | 59 | use ra_arena::{Arena, RawId, impl_arena_id}; |
60 | use ra_db::{FileId, Edition}; | 60 | use ra_db::{FileId, Edition}; |
61 | use test_utils::tested_by; | 61 | use test_utils::tested_by; |
62 | use ra_syntax::ast; | ||
62 | use ra_prof::profile; | 63 | use ra_prof::profile; |
63 | 64 | ||
64 | use crate::{ | 65 | use crate::{ |
65 | ModuleDef, Name, Crate, Module, Problem, | 66 | ModuleDef, Name, Crate, Module, |
66 | DefDatabase, Path, PathKind, HirFileId, | 67 | DefDatabase, Path, PathKind, HirFileId, Trait, |
67 | ids::{SourceItemId, SourceFileItemId, MacroCallId}, | 68 | ids::MacroDefId, |
69 | diagnostics::DiagnosticSink, | ||
70 | nameres::diagnostics::DefDiagnostic, | ||
71 | AstId, | ||
68 | }; | 72 | }; |
69 | 73 | ||
70 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; | 74 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; |
@@ -83,10 +87,8 @@ pub struct CrateDefMap { | |||
83 | extern_prelude: FxHashMap<Name, ModuleDef>, | 87 | extern_prelude: FxHashMap<Name, ModuleDef>, |
84 | root: CrateModuleId, | 88 | root: CrateModuleId, |
85 | modules: Arena<CrateModuleId, ModuleData>, | 89 | modules: Arena<CrateModuleId, ModuleData>, |
86 | macros: Arena<CrateMacroId, mbe::MacroRules>, | 90 | public_macros: FxHashMap<Name, MacroDefId>, |
87 | public_macros: FxHashMap<Name, CrateMacroId>, | 91 | diagnostics: Vec<DefDiagnostic>, |
88 | macro_resolutions: FxHashMap<MacroCallId, (Crate, CrateMacroId)>, | ||
89 | problems: CrateDefMapProblems, | ||
90 | } | 92 | } |
91 | 93 | ||
92 | impl std::ops::Index<CrateModuleId> for CrateDefMap { | 94 | impl std::ops::Index<CrateModuleId> for CrateDefMap { |
@@ -96,18 +98,6 @@ impl std::ops::Index<CrateModuleId> for CrateDefMap { | |||
96 | } | 98 | } |
97 | } | 99 | } |
98 | 100 | ||
99 | impl std::ops::Index<CrateMacroId> for CrateDefMap { | ||
100 | type Output = mbe::MacroRules; | ||
101 | fn index(&self, id: CrateMacroId) -> &mbe::MacroRules { | ||
102 | &self.macros[id] | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /// An ID of a macro, **local** to a specific crate | ||
107 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
108 | pub(crate) struct CrateMacroId(RawId); | ||
109 | impl_arena_id!(CrateMacroId); | ||
110 | |||
111 | /// An ID of a module, **local** to a specific crate | 101 | /// An ID of a module, **local** to a specific crate |
112 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 102 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
113 | pub(crate) struct CrateModuleId(RawId); | 103 | pub(crate) struct CrateModuleId(RawId); |
@@ -119,28 +109,13 @@ pub(crate) struct ModuleData { | |||
119 | pub(crate) children: FxHashMap<Name, CrateModuleId>, | 109 | pub(crate) children: FxHashMap<Name, CrateModuleId>, |
120 | pub(crate) scope: ModuleScope, | 110 | pub(crate) scope: ModuleScope, |
121 | /// None for root | 111 | /// None for root |
122 | pub(crate) declaration: Option<SourceItemId>, | 112 | pub(crate) declaration: Option<AstId<ast::Module>>, |
123 | /// None for inline modules. | 113 | /// None for inline modules. |
124 | /// | 114 | /// |
125 | /// Note that non-inline modules, by definition, live inside non-macro file. | 115 | /// Note that non-inline modules, by definition, live inside non-macro file. |
126 | pub(crate) definition: Option<FileId>, | 116 | pub(crate) definition: Option<FileId>, |
127 | } | 117 | } |
128 | 118 | ||
129 | #[derive(Default, Debug, PartialEq, Eq)] | ||
130 | pub(crate) struct CrateDefMapProblems { | ||
131 | problems: Vec<(SourceItemId, Problem)>, | ||
132 | } | ||
133 | |||
134 | impl CrateDefMapProblems { | ||
135 | fn add(&mut self, source_item_id: SourceItemId, problem: Problem) { | ||
136 | self.problems.push((source_item_id, problem)) | ||
137 | } | ||
138 | |||
139 | pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a SourceItemId, &'a Problem)> + 'a { | ||
140 | self.problems.iter().map(|(s, p)| (s, p)) | ||
141 | } | ||
142 | } | ||
143 | |||
144 | #[derive(Debug, Default, PartialEq, Eq, Clone)] | 119 | #[derive(Debug, Default, PartialEq, Eq, Clone)] |
145 | pub struct ModuleScope { | 120 | pub struct ModuleScope { |
146 | items: FxHashMap<Name, Resolution>, | 121 | items: FxHashMap<Name, Resolution>, |
@@ -153,6 +128,12 @@ impl ModuleScope { | |||
153 | pub fn get(&self, name: &Name) -> Option<&Resolution> { | 128 | pub fn get(&self, name: &Name) -> Option<&Resolution> { |
154 | self.items.get(name) | 129 | self.items.get(name) |
155 | } | 130 | } |
131 | pub fn traits<'a>(&'a self) -> impl Iterator<Item = Trait> + 'a { | ||
132 | self.items.values().filter_map(|r| match r.def.take_types() { | ||
133 | Some(ModuleDef::Trait(t)) => Some(t), | ||
134 | _ => None, | ||
135 | }) | ||
136 | } | ||
156 | } | 137 | } |
157 | 138 | ||
158 | #[derive(Debug, Clone, PartialEq, Eq, Default)] | 139 | #[derive(Debug, Clone, PartialEq, Eq, Default)] |
@@ -210,10 +191,8 @@ impl CrateDefMap { | |||
210 | prelude: None, | 191 | prelude: None, |
211 | root, | 192 | root, |
212 | modules, | 193 | modules, |
213 | macros: Arena::default(), | ||
214 | public_macros: FxHashMap::default(), | 194 | public_macros: FxHashMap::default(), |
215 | macro_resolutions: FxHashMap::default(), | 195 | diagnostics: Vec::new(), |
216 | problems: CrateDefMapProblems::default(), | ||
217 | } | 196 | } |
218 | }; | 197 | }; |
219 | let def_map = collector::collect_defs(db, def_map); | 198 | let def_map = collector::collect_defs(db, def_map); |
@@ -224,10 +203,6 @@ impl CrateDefMap { | |||
224 | self.root | 203 | self.root |
225 | } | 204 | } |
226 | 205 | ||
227 | pub(crate) fn problems(&self) -> &CrateDefMapProblems { | ||
228 | &self.problems | ||
229 | } | ||
230 | |||
231 | pub(crate) fn mk_module(&self, module_id: CrateModuleId) -> Module { | 206 | pub(crate) fn mk_module(&self, module_id: CrateModuleId) -> Module { |
232 | Module { krate: self.krate, module_id } | 207 | Module { krate: self.krate, module_id } |
233 | } | 208 | } |
@@ -240,19 +215,20 @@ impl CrateDefMap { | |||
240 | &self.extern_prelude | 215 | &self.extern_prelude |
241 | } | 216 | } |
242 | 217 | ||
243 | pub(crate) fn resolve_macro( | 218 | pub(crate) fn add_diagnostics( |
244 | &self, | 219 | &self, |
245 | macro_call_id: MacroCallId, | 220 | db: &impl DefDatabase, |
246 | ) -> Option<(Crate, CrateMacroId)> { | 221 | module: CrateModuleId, |
247 | self.macro_resolutions.get(¯o_call_id).map(|&it| it) | 222 | sink: &mut DiagnosticSink, |
223 | ) { | ||
224 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) | ||
248 | } | 225 | } |
249 | 226 | ||
250 | pub(crate) fn find_module_by_source( | 227 | pub(crate) fn find_module_by_source( |
251 | &self, | 228 | &self, |
252 | file_id: HirFileId, | 229 | file_id: HirFileId, |
253 | decl_id: Option<SourceFileItemId>, | 230 | decl_id: Option<AstId<ast::Module>>, |
254 | ) -> Option<CrateModuleId> { | 231 | ) -> Option<CrateModuleId> { |
255 | let decl_id = decl_id.map(|it| it.with_file_id(file_id)); | ||
256 | let (module_id, _module_data) = self.modules.iter().find(|(_module_id, module_data)| { | 232 | let (module_id, _module_data) = self.modules.iter().find(|(_module_id, module_data)| { |
257 | if decl_id.is_some() { | 233 | if decl_id.is_some() { |
258 | module_data.declaration == decl_id | 234 | module_data.declaration == decl_id |
@@ -452,3 +428,46 @@ impl CrateDefMap { | |||
452 | } | 428 | } |
453 | } | 429 | } |
454 | } | 430 | } |
431 | |||
432 | mod diagnostics { | ||
433 | use relative_path::RelativePathBuf; | ||
434 | use ra_syntax::{AstPtr, ast}; | ||
435 | |||
436 | use crate::{ | ||
437 | AstId, DefDatabase, | ||
438 | nameres::CrateModuleId, | ||
439 | diagnostics::{DiagnosticSink, UnresolvedModule}, | ||
440 | }; | ||
441 | |||
442 | #[derive(Debug, PartialEq, Eq)] | ||
443 | pub(super) enum DefDiagnostic { | ||
444 | UnresolvedModule { | ||
445 | module: CrateModuleId, | ||
446 | declaration: AstId<ast::Module>, | ||
447 | candidate: RelativePathBuf, | ||
448 | }, | ||
449 | } | ||
450 | |||
451 | impl DefDiagnostic { | ||
452 | pub(super) fn add_to( | ||
453 | &self, | ||
454 | db: &impl DefDatabase, | ||
455 | target_module: CrateModuleId, | ||
456 | sink: &mut DiagnosticSink, | ||
457 | ) { | ||
458 | match self { | ||
459 | DefDiagnostic::UnresolvedModule { module, declaration, candidate } => { | ||
460 | if *module != target_module { | ||
461 | return; | ||
462 | } | ||
463 | let decl = declaration.to_node(db); | ||
464 | sink.push(UnresolvedModule { | ||
465 | file: declaration.file_id(), | ||
466 | decl: AstPtr::new(&decl), | ||
467 | candidate: candidate.clone(), | ||
468 | }) | ||
469 | } | ||
470 | } | ||
471 | } | ||
472 | } | ||
473 | } | ||