aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/arena.rs2
-rw-r--r--crates/ra_hir/src/db.rs4
-rw-r--r--crates/ra_hir/src/function/mod.rs16
-rw-r--r--crates/ra_hir/src/function/scope.rs17
-rw-r--r--crates/ra_hir/src/lib.rs30
-rw-r--r--crates/ra_hir/src/module/imp.rs2
-rw-r--r--crates/ra_hir/src/module/mod.rs31
-rw-r--r--crates/ra_hir/src/module/nameres.rs134
-rw-r--r--crates/ra_hir/src/path.rs14
9 files changed, 69 insertions, 181 deletions
diff --git a/crates/ra_hir/src/arena.rs b/crates/ra_hir/src/arena.rs
index a752ec0c1..8d67ab1c9 100644
--- a/crates/ra_hir/src/arena.rs
+++ b/crates/ra_hir/src/arena.rs
@@ -8,7 +8,7 @@ use std::{
8 marker::PhantomData, 8 marker::PhantomData,
9}; 9};
10 10
11pub(crate) struct Id<T> { 11pub struct Id<T> {
12 idx: u32, 12 idx: u32,
13 _ty: PhantomData<fn() -> T>, 13 _ty: PhantomData<fn() -> T>,
14} 14}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index dbf8785fe..2f01bae6d 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -10,14 +10,14 @@ use crate::{
10 DefLoc, DefId, FnId, 10 DefLoc, DefId, FnId,
11 SourceFileItems, SourceItemId, 11 SourceFileItems, SourceItemId,
12 query_definitions, 12 query_definitions,
13 function::{FnScopes}, 13 FnScopes,
14 module::{ModuleId, ModuleTree, ModuleSource, 14 module::{ModuleId, ModuleTree, ModuleSource,
15 nameres::{ItemMap, InputModuleItems}}, 15 nameres::{ItemMap, InputModuleItems}},
16}; 16};
17 17
18salsa::query_group! { 18salsa::query_group! {
19 19
20pub(crate) trait HirDatabase: SyntaxDatabase 20pub trait HirDatabase: SyntaxDatabase
21 + AsRef<LocationIntener<DefLoc, DefId>> 21 + AsRef<LocationIntener<DefLoc, DefId>>
22 + AsRef<LocationIntener<SourceItemId, FnId>> 22 + AsRef<LocationIntener<SourceItemId, FnId>>
23{ 23{
diff --git a/crates/ra_hir/src/function/mod.rs b/crates/ra_hir/src/function/mod.rs
index a3ed00f02..c8af2e54f 100644
--- a/crates/ra_hir/src/function/mod.rs
+++ b/crates/ra_hir/src/function/mod.rs
@@ -15,10 +15,10 @@ use crate::{
15 FnId, HirDatabase, SourceItemId, 15 FnId, HirDatabase, SourceItemId,
16}; 16};
17 17
18pub(crate) use self::scope::FnScopes; 18pub use self::scope::FnScopes;
19 19
20impl FnId { 20impl FnId {
21 pub(crate) fn get(db: &impl HirDatabase, file_id: FileId, fn_def: ast::FnDef) -> FnId { 21 pub fn get(db: &impl HirDatabase, file_id: FileId, fn_def: ast::FnDef) -> FnId {
22 let file_items = db.file_items(file_id); 22 let file_items = db.file_items(file_id);
23 let item_id = file_items.id_of(fn_def.syntax()); 23 let item_id = file_items.id_of(fn_def.syntax());
24 let item_id = SourceItemId { file_id, item_id }; 24 let item_id = SourceItemId { file_id, item_id };
@@ -26,12 +26,12 @@ impl FnId {
26 } 26 }
27} 27}
28 28
29pub(crate) struct Function { 29pub struct Function {
30 fn_id: FnId, 30 fn_id: FnId,
31} 31}
32 32
33impl Function { 33impl Function {
34 pub(crate) fn guess_from_source( 34 pub fn guess_from_source(
35 db: &impl HirDatabase, 35 db: &impl HirDatabase,
36 file_id: FileId, 36 file_id: FileId,
37 fn_def: ast::FnDef, 37 fn_def: ast::FnDef,
@@ -40,7 +40,7 @@ impl Function {
40 Function { fn_id } 40 Function { fn_id }
41 } 41 }
42 42
43 pub(crate) fn guess_for_name_ref( 43 pub fn guess_for_name_ref(
44 db: &impl HirDatabase, 44 db: &impl HirDatabase,
45 file_id: FileId, 45 file_id: FileId,
46 name_ref: ast::NameRef, 46 name_ref: ast::NameRef,
@@ -48,7 +48,7 @@ impl Function {
48 Function::guess_for_node(db, file_id, name_ref.syntax()) 48 Function::guess_for_node(db, file_id, name_ref.syntax())
49 } 49 }
50 50
51 pub(crate) fn guess_for_bind_pat( 51 pub fn guess_for_bind_pat(
52 db: &impl HirDatabase, 52 db: &impl HirDatabase,
53 file_id: FileId, 53 file_id: FileId,
54 bind_pat: ast::BindPat, 54 bind_pat: ast::BindPat,
@@ -66,11 +66,11 @@ impl Function {
66 Some(res) 66 Some(res)
67 } 67 }
68 68
69 pub(crate) fn scope(&self, db: &impl HirDatabase) -> Arc<FnScopes> { 69 pub fn scope(&self, db: &impl HirDatabase) -> Arc<FnScopes> {
70 db.fn_scopes(self.fn_id) 70 db.fn_scopes(self.fn_id)
71 } 71 }
72 72
73 pub(crate) fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> { 73 pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> {
74 let syntax = db.fn_syntax(self.fn_id); 74 let syntax = db.fn_syntax(self.fn_id);
75 FnSignatureInfo::new(syntax.borrowed()) 75 FnSignatureInfo::new(syntax.borrowed())
76 } 76 }
diff --git a/crates/ra_hir/src/function/scope.rs b/crates/ra_hir/src/function/scope.rs
index c8b6b1934..863453291 100644
--- a/crates/ra_hir/src/function/scope.rs
+++ b/crates/ra_hir/src/function/scope.rs
@@ -15,7 +15,7 @@ pub(crate) type ScopeId = Id<ScopeData>;
15 15
16#[derive(Debug, PartialEq, Eq)] 16#[derive(Debug, PartialEq, Eq)]
17pub struct FnScopes { 17pub struct FnScopes {
18 pub(crate) self_param: Option<LocalSyntaxPtr>, 18 pub self_param: Option<LocalSyntaxPtr>,
19 scopes: Arena<ScopeData>, 19 scopes: Arena<ScopeData>,
20 scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>, 20 scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>,
21} 21}
@@ -27,13 +27,13 @@ pub struct ScopeEntry {
27} 27}
28 28
29#[derive(Debug, PartialEq, Eq)] 29#[derive(Debug, PartialEq, Eq)]
30pub(crate) struct ScopeData { 30pub struct ScopeData {
31 parent: Option<ScopeId>, 31 parent: Option<ScopeId>,
32 entries: Vec<ScopeEntry>, 32 entries: Vec<ScopeEntry>,
33} 33}
34 34
35impl FnScopes { 35impl FnScopes {
36 pub(crate) fn new(fn_def: ast::FnDef) -> FnScopes { 36 pub fn new(fn_def: ast::FnDef) -> FnScopes {
37 let mut scopes = FnScopes { 37 let mut scopes = FnScopes {
38 self_param: fn_def 38 self_param: fn_def
39 .param_list() 39 .param_list()
@@ -49,7 +49,7 @@ impl FnScopes {
49 } 49 }
50 scopes 50 scopes
51 } 51 }
52 pub(crate) fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { 52 pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] {
53 &self.scopes[scope].entries 53 &self.scopes[scope].entries
54 } 54 }
55 pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a { 55 pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a {
@@ -57,10 +57,7 @@ impl FnScopes {
57 self.scopes[scope].parent 57 self.scopes[scope].parent
58 }) 58 })
59 } 59 }
60 pub(crate) fn resolve_local_name<'a>( 60 pub fn resolve_local_name<'a>(&'a self, name_ref: ast::NameRef) -> Option<&'a ScopeEntry> {
61 &'a self,
62 name_ref: ast::NameRef,
63 ) -> Option<&'a ScopeEntry> {
64 let mut shadowed = FxHashSet::default(); 61 let mut shadowed = FxHashSet::default();
65 let ret = self 62 let ret = self
66 .scope_chain(name_ref.syntax()) 63 .scope_chain(name_ref.syntax())
@@ -138,10 +135,10 @@ impl ScopeEntry {
138 }; 135 };
139 Some(res) 136 Some(res)
140 } 137 }
141 pub(crate) fn name(&self) -> &SmolStr { 138 pub fn name(&self) -> &SmolStr {
142 &self.name 139 &self.name
143 } 140 }
144 pub(crate) fn ptr(&self) -> LocalSyntaxPtr { 141 pub fn ptr(&self) -> LocalSyntaxPtr {
145 self.ptr 142 self.ptr
146 } 143 }
147} 144}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 7bf06c7f7..f13f0107e 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -14,7 +14,7 @@ macro_rules! ctry {
14 }; 14 };
15} 15}
16 16
17pub(crate) mod db; 17pub mod db;
18mod query_definitions; 18mod query_definitions;
19mod function; 19mod function;
20mod module; 20mod module;
@@ -31,36 +31,36 @@ use crate::{
31 arena::{Arena, Id}, 31 arena::{Arena, Id},
32}; 32};
33 33
34pub(crate) use self::{ 34pub use self::{
35 path::{Path, PathKind}, 35 path::{Path, PathKind},
36 module::{Module, ModuleId, Problem}, 36 module::{Module, ModuleId, Problem, nameres::ItemMap},
37 function::{Function, FnScopes}, 37 function::{Function, FnScopes},
38}; 38};
39 39
40pub use self::function::FnSignatureInfo; 40pub use self::function::FnSignatureInfo;
41 41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43pub(crate) struct FnId(u32); 43pub struct FnId(u32);
44ra_db::impl_numeric_id!(FnId); 44ra_db::impl_numeric_id!(FnId);
45 45
46impl FnId { 46impl FnId {
47 pub(crate) fn from_loc( 47 pub fn from_loc(
48 db: &impl AsRef<LocationIntener<SourceItemId, FnId>>, 48 db: &impl AsRef<LocationIntener<SourceItemId, FnId>>,
49 loc: &SourceItemId, 49 loc: &SourceItemId,
50 ) -> FnId { 50 ) -> FnId {
51 db.as_ref().loc2id(loc) 51 db.as_ref().loc2id(loc)
52 } 52 }
53 pub(crate) fn loc(self, db: &impl AsRef<LocationIntener<SourceItemId, FnId>>) -> SourceItemId { 53 pub fn loc(self, db: &impl AsRef<LocationIntener<SourceItemId, FnId>>) -> SourceItemId {
54 db.as_ref().id2loc(self) 54 db.as_ref().id2loc(self)
55 } 55 }
56} 56}
57 57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
59pub(crate) struct DefId(u32); 59pub struct DefId(u32);
60ra_db::impl_numeric_id!(DefId); 60ra_db::impl_numeric_id!(DefId);
61 61
62#[derive(Clone, Debug, PartialEq, Eq, Hash)] 62#[derive(Clone, Debug, PartialEq, Eq, Hash)]
63pub(crate) enum DefLoc { 63pub enum DefLoc {
64 Module { 64 Module {
65 id: ModuleId, 65 id: ModuleId,
66 source_root: SourceRootId, 66 source_root: SourceRootId,
@@ -71,24 +71,24 @@ pub(crate) enum DefLoc {
71} 71}
72 72
73impl DefId { 73impl DefId {
74 pub(crate) fn loc(self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefLoc { 74 pub fn loc(self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefLoc {
75 db.as_ref().id2loc(self) 75 db.as_ref().id2loc(self)
76 } 76 }
77} 77}
78 78
79impl DefLoc { 79impl DefLoc {
80 pub(crate) fn id(&self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefId { 80 pub fn id(&self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefId {
81 db.as_ref().loc2id(&self) 81 db.as_ref().loc2id(&self)
82 } 82 }
83} 83}
84 84
85pub(crate) enum Def { 85pub enum Def {
86 Module(Module), 86 Module(Module),
87 Item, 87 Item,
88} 88}
89 89
90impl DefId { 90impl DefId {
91 pub(crate) fn resolve(self, db: &impl HirDatabase) -> Cancelable<Def> { 91 pub fn resolve(self, db: &impl HirDatabase) -> Cancelable<Def> {
92 let loc = self.loc(db); 92 let loc = self.loc(db);
93 let res = match loc { 93 let res = match loc {
94 DefLoc::Module { id, source_root } => { 94 DefLoc::Module { id, source_root } => {
@@ -106,14 +106,14 @@ impl DefId {
106pub(crate) type SourceFileItemId = Id<SyntaxNode>; 106pub(crate) type SourceFileItemId = Id<SyntaxNode>;
107 107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
109pub(crate) struct SourceItemId { 109pub struct SourceItemId {
110 file_id: FileId, 110 file_id: FileId,
111 item_id: SourceFileItemId, 111 item_id: SourceFileItemId,
112} 112}
113 113
114/// Maps item's `SyntaxNode`s to `SourceFileItemId` and back. 114/// Maps item's `SyntaxNode`s to `SourceFileItemId` and back.
115#[derive(Debug, PartialEq, Eq, Default)] 115#[derive(Debug, PartialEq, Eq, Default)]
116pub(crate) struct SourceFileItems { 116pub struct SourceFileItems {
117 arena: Arena<SyntaxNode>, 117 arena: Arena<SyntaxNode>,
118} 118}
119 119
@@ -121,7 +121,7 @@ impl SourceFileItems {
121 fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId { 121 fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId {
122 self.arena.alloc(item) 122 self.arena.alloc(item)
123 } 123 }
124 fn id_of(&self, item: SyntaxNodeRef) -> SourceFileItemId { 124 pub fn id_of(&self, item: SyntaxNodeRef) -> SourceFileItemId {
125 let (id, _item) = self 125 let (id, _item) = self
126 .arena 126 .arena
127 .iter() 127 .iter()
diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs
index d55fa3e6b..76ea129a7 100644
--- a/crates/ra_hir/src/module/imp.rs
+++ b/crates/ra_hir/src/module/imp.rs
@@ -18,7 +18,7 @@ use super::{
18}; 18};
19 19
20#[derive(Clone, Hash, PartialEq, Eq, Debug)] 20#[derive(Clone, Hash, PartialEq, Eq, Debug)]
21pub(crate) enum Submodule { 21pub enum Submodule {
22 Declaration(SmolStr), 22 Declaration(SmolStr),
23 Definition(SmolStr, ModuleSource), 23 Definition(SmolStr, ModuleSource),
24} 24}
diff --git a/crates/ra_hir/src/module/mod.rs b/crates/ra_hir/src/module/mod.rs
index 81b9f948d..a011fd53e 100644
--- a/crates/ra_hir/src/module/mod.rs
+++ b/crates/ra_hir/src/module/mod.rs
@@ -18,15 +18,16 @@ use crate::{
18 arena::{Arena, Id}, 18 arena::{Arena, Id},
19}; 19};
20 20
21pub(crate) use self::nameres::ModuleScope; 21pub use self::nameres::ModuleScope;
22 22
23/// `Module` is API entry point to get all the information 23/// `Module` is API entry point to get all the information
24/// about a particular module. 24/// about a particular module.
25#[derive(Debug, Clone)] 25#[derive(Debug, Clone)]
26pub(crate) struct Module { 26pub struct Module {
27 tree: Arc<ModuleTree>, 27 tree: Arc<ModuleTree>,
28 source_root_id: SourceRootId, 28 source_root_id: SourceRootId,
29 module_id: ModuleId, 29 //TODO: make private
30 pub module_id: ModuleId,
30} 31}
31 32
32impl Module { 33impl Module {
@@ -145,17 +146,13 @@ impl Module {
145 } 146 }
146 147
147 /// Returns a `ModuleScope`: a set of items, visible in this module. 148 /// Returns a `ModuleScope`: a set of items, visible in this module.
148 pub(crate) fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { 149 pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
149 let item_map = db.item_map(self.source_root_id)?; 150 let item_map = db.item_map(self.source_root_id)?;
150 let res = item_map.per_module[&self.module_id].clone(); 151 let res = item_map.per_module[&self.module_id].clone();
151 Ok(res) 152 Ok(res)
152 } 153 }
153 154
154 pub(crate) fn resolve_path( 155 pub fn resolve_path(&self, db: &impl HirDatabase, path: Path) -> Cancelable<Option<DefId>> {
155 &self,
156 db: &impl HirDatabase,
157 path: Path,
158 ) -> Cancelable<Option<DefId>> {
159 let mut curr = match path.kind { 156 let mut curr = match path.kind {
160 PathKind::Crate => self.crate_root(), 157 PathKind::Crate => self.crate_root(),
161 PathKind::Self_ | PathKind::Plain => self.clone(), 158 PathKind::Self_ | PathKind::Plain => self.clone(),
@@ -188,7 +185,7 @@ impl Module {
188/// (which can have multiple parents) to the precise world of modules (which 185/// (which can have multiple parents) to the precise world of modules (which
189/// always have one parent). 186/// always have one parent).
190#[derive(Default, Debug, PartialEq, Eq)] 187#[derive(Default, Debug, PartialEq, Eq)]
191pub(crate) struct ModuleTree { 188pub struct ModuleTree {
192 mods: Arena<ModuleData>, 189 mods: Arena<ModuleData>,
193 links: Arena<LinkData>, 190 links: Arena<LinkData>,
194} 191}
@@ -214,19 +211,19 @@ impl ModuleTree {
214/// `ModuleSource` is the syntax tree element that produced this module: 211/// `ModuleSource` is the syntax tree element that produced this module:
215/// either a file, or an inlinde module. 212/// either a file, or an inlinde module.
216#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 213#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
217pub(crate) enum ModuleSource { 214pub enum ModuleSource {
218 SourceFile(FileId), 215 SourceFile(FileId),
219 Module(SourceItemId), 216 Module(SourceItemId),
220} 217}
221 218
222/// An owned syntax node for a module. Unlike `ModuleSource`, 219/// An owned syntax node for a module. Unlike `ModuleSource`,
223/// this holds onto the AST for the whole file. 220/// this holds onto the AST for the whole file.
224pub(crate) enum ModuleSourceNode { 221pub enum ModuleSourceNode {
225 SourceFile(ast::SourceFileNode), 222 SourceFile(ast::SourceFileNode),
226 Module(ast::ModuleNode), 223 Module(ast::ModuleNode),
227} 224}
228 225
229pub(crate) type ModuleId = Id<ModuleData>; 226pub type ModuleId = Id<ModuleData>;
230type LinkId = Id<LinkData>; 227type LinkId = Id<LinkData>;
231 228
232#[derive(Clone, Debug, Hash, PartialEq, Eq)] 229#[derive(Clone, Debug, Hash, PartialEq, Eq)]
@@ -308,7 +305,7 @@ impl LinkId {
308} 305}
309 306
310#[derive(Debug, PartialEq, Eq, Hash)] 307#[derive(Debug, PartialEq, Eq, Hash)]
311pub(crate) struct ModuleData { 308pub struct ModuleData {
312 source: ModuleSource, 309 source: ModuleSource,
313 parent: Option<LinkId>, 310 parent: Option<LinkId>,
314 children: Vec<LinkId>, 311 children: Vec<LinkId>,
@@ -327,21 +324,21 @@ impl ModuleSource {
327 ModuleSource::Module(id) 324 ModuleSource::Module(id)
328 } 325 }
329 326
330 pub(crate) fn as_file(self) -> Option<FileId> { 327 pub fn as_file(self) -> Option<FileId> {
331 match self { 328 match self {
332 ModuleSource::SourceFile(f) => Some(f), 329 ModuleSource::SourceFile(f) => Some(f),
333 ModuleSource::Module(..) => None, 330 ModuleSource::Module(..) => None,
334 } 331 }
335 } 332 }
336 333
337 pub(crate) fn file_id(self) -> FileId { 334 pub fn file_id(self) -> FileId {
338 match self { 335 match self {
339 ModuleSource::SourceFile(f) => f, 336 ModuleSource::SourceFile(f) => f,
340 ModuleSource::Module(source_item_id) => source_item_id.file_id, 337 ModuleSource::Module(source_item_id) => source_item_id.file_id,
341 } 338 }
342 } 339 }
343 340
344 pub(crate) fn resolve(self, db: &impl HirDatabase) -> ModuleSourceNode { 341 pub fn resolve(self, db: &impl HirDatabase) -> ModuleSourceNode {
345 match self { 342 match self {
346 ModuleSource::SourceFile(file_id) => { 343 ModuleSource::SourceFile(file_id) => {
347 let syntax = db.source_file(file_id); 344 let syntax = db.source_file(file_id);
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs
index 513a37646..837a8d5ae 100644
--- a/crates/ra_hir/src/module/nameres.rs
+++ b/crates/ra_hir/src/module/nameres.rs
@@ -38,20 +38,20 @@ use crate::{
38/// Item map is the result of the name resolution. Item map contains, for each 38/// Item map is the result of the name resolution. Item map contains, for each
39/// module, the set of visible items. 39/// module, the set of visible items.
40#[derive(Default, Debug, PartialEq, Eq)] 40#[derive(Default, Debug, PartialEq, Eq)]
41pub(crate) struct ItemMap { 41pub struct ItemMap {
42 pub(crate) per_module: FxHashMap<ModuleId, ModuleScope>, 42 pub per_module: FxHashMap<ModuleId, ModuleScope>,
43} 43}
44 44
45#[derive(Debug, Default, PartialEq, Eq, Clone)] 45#[derive(Debug, Default, PartialEq, Eq, Clone)]
46pub(crate) struct ModuleScope { 46pub struct ModuleScope {
47 items: FxHashMap<SmolStr, Resolution>, 47 pub items: FxHashMap<SmolStr, Resolution>,
48} 48}
49 49
50impl ModuleScope { 50impl ModuleScope {
51 pub(crate) fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a { 51 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a {
52 self.items.iter() 52 self.items.iter()
53 } 53 }
54 pub(crate) fn get(&self, name: &SmolStr) -> Option<&Resolution> { 54 pub fn get(&self, name: &SmolStr) -> Option<&Resolution> {
55 self.items.get(name) 55 self.items.get(name)
56 } 56 }
57} 57}
@@ -63,7 +63,7 @@ impl ModuleScope {
63/// recomputing name res: if `InputModuleItems` are the same, we can avoid 63/// recomputing name res: if `InputModuleItems` are the same, we can avoid
64/// running name resolution. 64/// running name resolution.
65#[derive(Debug, Default, PartialEq, Eq)] 65#[derive(Debug, Default, PartialEq, Eq)]
66pub(crate) struct InputModuleItems { 66pub struct InputModuleItems {
67 items: Vec<ModuleItem>, 67 items: Vec<ModuleItem>,
68 imports: Vec<Import>, 68 imports: Vec<Import>,
69} 69}
@@ -89,13 +89,13 @@ struct Import {
89} 89}
90 90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)] 91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub(crate) struct NamedImport { 92pub struct NamedImport {
93 file_item_id: SourceFileItemId, 93 pub file_item_id: SourceFileItemId,
94 relative_range: TextRange, 94 pub relative_range: TextRange,
95} 95}
96 96
97impl NamedImport { 97impl NamedImport {
98 pub(crate) fn range(&self, db: &impl HirDatabase, file_id: FileId) -> TextRange { 98 pub fn range(&self, db: &impl HirDatabase, file_id: FileId) -> TextRange {
99 let source_item_id = SourceItemId { 99 let source_item_id = SourceItemId {
100 file_id, 100 file_id,
101 item_id: self.file_item_id, 101 item_id: self.file_item_id,
@@ -115,11 +115,11 @@ enum ImportKind {
115/// Resolution is basically `DefId` atm, but it should account for stuff like 115/// Resolution is basically `DefId` atm, but it should account for stuff like
116/// multiple namespaces, ambiguity and errors. 116/// multiple namespaces, ambiguity and errors.
117#[derive(Debug, Clone, PartialEq, Eq)] 117#[derive(Debug, Clone, PartialEq, Eq)]
118pub(crate) struct Resolution { 118pub struct Resolution {
119 /// None for unresolved 119 /// None for unresolved
120 pub(crate) def_id: Option<DefId>, 120 pub def_id: Option<DefId>,
121 /// ident by whitch this is imported into local scope. 121 /// ident by whitch this is imported into local scope.
122 pub(crate) import: Option<NamedImport>, 122 pub import: Option<NamedImport>,
123} 123}
124 124
125// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 125// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -336,109 +336,3 @@ where
336 f(module_items) 336 f(module_items)
337 } 337 }
338} 338}
339
340#[cfg(test)]
341mod tests {
342 use ra_db::FilesDatabase;
343 use crate::{
344 AnalysisChange,
345 mock_analysis::{MockAnalysis, analysis_and_position},
346 hir::{self, HirDatabase},
347};
348 use super::*;
349
350 fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
351 let (analysis, pos) = analysis_and_position(fixture);
352 let db = analysis.imp.db;
353 let source_root = db.file_source_root(pos.file_id);
354 let descr = hir::Module::guess_from_position(&*db, pos)
355 .unwrap()
356 .unwrap();
357 let module_id = descr.module_id;
358 (db.item_map(source_root).unwrap(), module_id)
359 }
360
361 #[test]
362 fn test_item_map() {
363 let (item_map, module_id) = item_map(
364 "
365 //- /lib.rs
366 mod foo;
367
368 use crate::foo::bar::Baz;
369 <|>
370
371 //- /foo/mod.rs
372 pub mod bar;
373
374 //- /foo/bar.rs
375 pub struct Baz;
376 ",
377 );
378 let name = SmolStr::from("Baz");
379 let resolution = &item_map.per_module[&module_id].items[&name];
380 assert!(resolution.def_id.is_some());
381 }
382
383 #[test]
384 fn typing_inside_a_function_should_not_invalidate_item_map() {
385 let mock_analysis = MockAnalysis::with_files(
386 "
387 //- /lib.rs
388 mod foo;
389
390 use crate::foo::bar::Baz;
391
392 fn foo() -> i32 {
393 1 + 1
394 }
395 //- /foo/mod.rs
396 pub mod bar;
397
398 //- /foo/bar.rs
399 pub struct Baz;
400 ",
401 );
402
403 let file_id = mock_analysis.id_of("/lib.rs");
404 let mut host = mock_analysis.analysis_host();
405
406 let source_root = host.analysis().imp.db.file_source_root(file_id);
407
408 {
409 let db = host.analysis().imp.db;
410 let events = db.log_executed(|| {
411 db.item_map(source_root).unwrap();
412 });
413 assert!(format!("{:?}", events).contains("item_map"))
414 }
415
416 let mut change = AnalysisChange::new();
417
418 change.change_file(
419 file_id,
420 "
421 mod foo;
422
423 use crate::foo::bar::Baz;
424
425 fn foo() -> i32 { 92 }
426 "
427 .to_string(),
428 );
429
430 host.apply_change(change);
431
432 {
433 let db = host.analysis().imp.db;
434 let events = db.log_executed(|| {
435 db.item_map(source_root).unwrap();
436 });
437 assert!(
438 !format!("{:?}", events).contains("_item_map"),
439 "{:#?}",
440 events
441 )
442 }
443 }
444}
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 8279daf4b..4a2e427cd 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -1,13 +1,13 @@
1use ra_syntax::{SmolStr, ast, AstNode, TextRange}; 1use ra_syntax::{SmolStr, ast, AstNode, TextRange};
2 2
3#[derive(Debug, Clone, PartialEq, Eq)] 3#[derive(Debug, Clone, PartialEq, Eq)]
4pub(crate) struct Path { 4pub struct Path {
5 pub(crate) kind: PathKind, 5 pub kind: PathKind,
6 pub(crate) segments: Vec<SmolStr>, 6 pub segments: Vec<SmolStr>,
7} 7}
8 8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)] 9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub(crate) enum PathKind { 10pub enum PathKind {
11 Plain, 11 Plain,
12 Self_, 12 Self_,
13 Super, 13 Super,
@@ -16,14 +16,14 @@ pub(crate) enum PathKind {
16 16
17impl Path { 17impl Path {
18 /// Calls `cb` with all paths, represented by this use item. 18 /// Calls `cb` with all paths, represented by this use item.
19 pub(crate) fn expand_use_item(item: ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) { 19 pub fn expand_use_item(item: ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) {
20 if let Some(tree) = item.use_tree() { 20 if let Some(tree) = item.use_tree() {
21 expand_use_tree(None, tree, &mut cb); 21 expand_use_tree(None, tree, &mut cb);
22 } 22 }
23 } 23 }
24 24
25 /// Converts an `ast::Path` to `Path`. Works with use trees. 25 /// Converts an `ast::Path` to `Path`. Works with use trees.
26 pub(crate) fn from_ast(mut path: ast::Path) -> Option<Path> { 26 pub fn from_ast(mut path: ast::Path) -> Option<Path> {
27 let mut kind = PathKind::Plain; 27 let mut kind = PathKind::Plain;
28 let mut segments = Vec::new(); 28 let mut segments = Vec::new();
29 loop { 29 loop {
@@ -64,7 +64,7 @@ impl Path {
64 } 64 }
65 65
66 /// `true` is this path is a single identifier, like `foo` 66 /// `true` is this path is a single identifier, like `foo`
67 pub(crate) fn is_ident(&self) -> bool { 67 pub fn is_ident(&self) -> bool {
68 self.kind == PathKind::Plain && self.segments.len() == 1 68 self.kind == PathKind::Plain && self.segments.len() == 1
69 } 69 }
70} 70}