aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/nameres.rs')
-rw-r--r--crates/ra_hir/src/nameres.rs153
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.
17pub(crate) mod lower;
18use lower::*;
19
17use std::sync::Arc; 20use std::sync::Arc;
18 21
19use rustc_hash::{FxHashMap, FxHashSet}; 22use rustc_hash::{FxHashMap, FxHashSet};
20use ra_syntax::{ 23use ra_syntax::SyntaxKind::*;
21 TextRange, 24use ra_db::SourceRootId;
22 SyntaxKind::{self, *},
23 ast::{self, AstNode}
24};
25use ra_db::{SourceRootId, FileId};
26 25
27use crate::{ 26use 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)]
66pub struct InputModuleItems {
67 pub(crate) items: Vec<ModuleItem>,
68 imports: Vec<Import>,
69}
70
71#[derive(Debug, PartialEq, Eq)]
72pub(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)]
80enum Vis {
81 // Priv,
82 Other,
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
86struct Import {
87 path: Path,
88 kind: ImportKind,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub struct NamedImport {
93 pub file_item_id: SourceFileItemId,
94 pub relative_range: TextRange,
95}
96
97impl 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)]
112enum 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
213impl 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
272impl 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
293pub(crate) struct Resolver<'a, DB> { 152pub(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>>,