diff options
Diffstat (limited to 'crates/ra_hir/src/nameres.rs')
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 153 |
1 files changed, 6 insertions, 147 deletions
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 484f668d0..aea95e08c 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -14,23 +14,20 @@ | |||
14 | //! modifications (that is, typing inside a function should not change IMIs), | 14 | //! modifications (that is, typing inside a function should not change IMIs), |
15 | //! so that the results of name resolution can be preserved unless the module | 15 | //! so that the results of name resolution can be preserved unless the module |
16 | //! structure itself is modified. | 16 | //! structure itself is modified. |
17 | pub(crate) mod lower; | ||
18 | use lower::*; | ||
19 | |||
17 | use std::sync::Arc; | 20 | use std::sync::Arc; |
18 | 21 | ||
19 | use rustc_hash::{FxHashMap, FxHashSet}; | 22 | use rustc_hash::{FxHashMap, FxHashSet}; |
20 | use ra_syntax::{ | 23 | use ra_syntax::SyntaxKind::*; |
21 | TextRange, | 24 | use ra_db::SourceRootId; |
22 | SyntaxKind::{self, *}, | ||
23 | ast::{self, AstNode} | ||
24 | }; | ||
25 | use ra_db::{SourceRootId, FileId}; | ||
26 | 25 | ||
27 | use crate::{ | 26 | use crate::{ |
28 | HirFileId, | ||
29 | DefId, DefLoc, DefKind, | 27 | DefId, DefLoc, DefKind, |
30 | SourceItemId, SourceFileItemId, SourceFileItems, | ||
31 | Path, PathKind, | 28 | Path, PathKind, |
32 | HirDatabase, Crate, | 29 | HirDatabase, Crate, |
33 | Name, AsName, | 30 | Name, |
34 | module_tree::{ModuleId, ModuleTree}, | 31 | module_tree::{ModuleId, ModuleTree}, |
35 | }; | 32 | }; |
36 | 33 | ||
@@ -56,64 +53,6 @@ impl ModuleScope { | |||
56 | } | 53 | } |
57 | } | 54 | } |
58 | 55 | ||
59 | /// A set of items and imports declared inside a module, without relation to | ||
60 | /// other modules. | ||
61 | /// | ||
62 | /// This sits in-between raw syntax and name resolution and allows us to avoid | ||
63 | /// recomputing name res: if two instance of `InputModuleItems` are the same, we | ||
64 | /// can avoid redoing name resolution. | ||
65 | #[derive(Debug, Default, PartialEq, Eq)] | ||
66 | pub struct InputModuleItems { | ||
67 | pub(crate) items: Vec<ModuleItem>, | ||
68 | imports: Vec<Import>, | ||
69 | } | ||
70 | |||
71 | #[derive(Debug, PartialEq, Eq)] | ||
72 | pub(crate) struct ModuleItem { | ||
73 | pub(crate) id: SourceItemId, | ||
74 | pub(crate) name: Name, | ||
75 | kind: SyntaxKind, | ||
76 | vis: Vis, | ||
77 | } | ||
78 | |||
79 | #[derive(Debug, PartialEq, Eq)] | ||
80 | enum Vis { | ||
81 | // Priv, | ||
82 | Other, | ||
83 | } | ||
84 | |||
85 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
86 | struct Import { | ||
87 | path: Path, | ||
88 | kind: ImportKind, | ||
89 | } | ||
90 | |||
91 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
92 | pub struct NamedImport { | ||
93 | pub file_item_id: SourceFileItemId, | ||
94 | pub relative_range: TextRange, | ||
95 | } | ||
96 | |||
97 | impl NamedImport { | ||
98 | // FIXME: this is only here for one use-case in completion. Seems like a | ||
99 | // pretty gross special case. | ||
100 | pub fn range(&self, db: &impl HirDatabase, file_id: FileId) -> TextRange { | ||
101 | let source_item_id = SourceItemId { | ||
102 | file_id: file_id.into(), | ||
103 | item_id: Some(self.file_item_id), | ||
104 | }; | ||
105 | let syntax = db.file_item(source_item_id); | ||
106 | let offset = syntax.range().start(); | ||
107 | self.relative_range + offset | ||
108 | } | ||
109 | } | ||
110 | |||
111 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
112 | enum ImportKind { | ||
113 | Glob, | ||
114 | Named(NamedImport), | ||
115 | } | ||
116 | |||
117 | /// `Resolution` is basically `DefId` atm, but it should account for stuff like | 56 | /// `Resolution` is basically `DefId` atm, but it should account for stuff like |
118 | /// multiple namespaces, ambiguity and errors. | 57 | /// multiple namespaces, ambiguity and errors. |
119 | #[derive(Debug, Clone, PartialEq, Eq)] | 58 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -210,86 +149,6 @@ impl<T> PerNs<T> { | |||
210 | } | 149 | } |
211 | } | 150 | } |
212 | 151 | ||
213 | impl InputModuleItems { | ||
214 | pub(crate) fn add_item( | ||
215 | &mut self, | ||
216 | file_id: HirFileId, | ||
217 | file_items: &SourceFileItems, | ||
218 | item: &ast::ModuleItem, | ||
219 | ) -> Option<()> { | ||
220 | match item.kind() { | ||
221 | ast::ModuleItemKind::StructDef(it) => { | ||
222 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
223 | } | ||
224 | ast::ModuleItemKind::EnumDef(it) => { | ||
225 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
226 | } | ||
227 | ast::ModuleItemKind::FnDef(it) => { | ||
228 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
229 | } | ||
230 | ast::ModuleItemKind::TraitDef(it) => { | ||
231 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
232 | } | ||
233 | ast::ModuleItemKind::TypeDef(it) => { | ||
234 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
235 | } | ||
236 | ast::ModuleItemKind::ImplBlock(_) => { | ||
237 | // impls don't define items | ||
238 | } | ||
239 | ast::ModuleItemKind::UseItem(it) => self.add_use_item(file_items, it), | ||
240 | ast::ModuleItemKind::ExternCrateItem(_) => { | ||
241 | // TODO | ||
242 | } | ||
243 | ast::ModuleItemKind::ConstDef(it) => { | ||
244 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
245 | } | ||
246 | ast::ModuleItemKind::StaticDef(it) => { | ||
247 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
248 | } | ||
249 | ast::ModuleItemKind::Module(it) => { | ||
250 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
251 | } | ||
252 | } | ||
253 | Some(()) | ||
254 | } | ||
255 | |||
256 | fn add_use_item(&mut self, file_items: &SourceFileItems, item: &ast::UseItem) { | ||
257 | let file_item_id = file_items.id_of_unchecked(item.syntax()); | ||
258 | let start_offset = item.syntax().range().start(); | ||
259 | Path::expand_use_item(item, |path, range| { | ||
260 | let kind = match range { | ||
261 | None => ImportKind::Glob, | ||
262 | Some(range) => ImportKind::Named(NamedImport { | ||
263 | file_item_id, | ||
264 | relative_range: range - start_offset, | ||
265 | }), | ||
266 | }; | ||
267 | self.imports.push(Import { kind, path }) | ||
268 | }) | ||
269 | } | ||
270 | } | ||
271 | |||
272 | impl ModuleItem { | ||
273 | fn new( | ||
274 | file_id: HirFileId, | ||
275 | file_items: &SourceFileItems, | ||
276 | item: &impl ast::NameOwner, | ||
277 | ) -> Option<ModuleItem> { | ||
278 | let name = item.name()?.as_name(); | ||
279 | let kind = item.syntax().kind(); | ||
280 | let vis = Vis::Other; | ||
281 | let item_id = Some(file_items.id_of_unchecked(item.syntax())); | ||
282 | let id = SourceItemId { file_id, item_id }; | ||
283 | let res = ModuleItem { | ||
284 | id, | ||
285 | name, | ||
286 | kind, | ||
287 | vis, | ||
288 | }; | ||
289 | Some(res) | ||
290 | } | ||
291 | } | ||
292 | |||
293 | pub(crate) struct Resolver<'a, DB> { | 152 | pub(crate) struct Resolver<'a, DB> { |
294 | db: &'a DB, | 153 | db: &'a DB, |
295 | input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, | 154 | input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, |