diff options
-rw-r--r-- | crates/ra_analysis/src/completion/reference_completion.rs | 7 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/mod.rs | 26 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 24 |
3 files changed, 46 insertions, 11 deletions
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index a0af59178..858b52e76 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs | |||
@@ -13,6 +13,7 @@ use crate::{ | |||
13 | descriptors::{ | 13 | descriptors::{ |
14 | module::{ModuleDescriptor}, | 14 | module::{ModuleDescriptor}, |
15 | function::FnScopes, | 15 | function::FnScopes, |
16 | Def, | ||
16 | Path, | 17 | Path, |
17 | }, | 18 | }, |
18 | Cancelable | 19 | Cancelable |
@@ -156,10 +157,14 @@ fn complete_path( | |||
156 | return Ok(()); | 157 | return Ok(()); |
157 | } | 158 | } |
158 | path.segments.pop(); | 159 | path.segments.pop(); |
159 | let target_module = match module.resolve_path(db, path)? { | 160 | let def_id = match module.resolve_path(db, path)? { |
160 | None => return Ok(()), | 161 | None => return Ok(()), |
161 | Some(it) => it, | 162 | Some(it) => it, |
162 | }; | 163 | }; |
164 | let target_module = match def_id.resolve(db)? { | ||
165 | Def::Module(it) => it, | ||
166 | Def::Item => return Ok(()), | ||
167 | }; | ||
163 | let module_scope = target_module.scope(db)?; | 168 | let module_scope = target_module.scope(db)?; |
164 | let completions = module_scope.entries().map(|(name, _res)| CompletionItem { | 169 | let completions = module_scope.entries().map(|(name, _res)| CompletionItem { |
165 | label: name.to_string(), | 170 | label: name.to_string(), |
diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index 98094d9ee..7a1bcf447 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs | |||
@@ -13,9 +13,12 @@ use crate::{ | |||
13 | FileId, | 13 | FileId, |
14 | db::SyntaxDatabase, | 14 | db::SyntaxDatabase, |
15 | descriptors::function::{resolve_local_name, FnId, FnScopes}, | 15 | descriptors::function::{resolve_local_name, FnId, FnScopes}, |
16 | descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems, FileItems}}, | 16 | descriptors::module::{ |
17 | ModuleId, ModuleTree, ModuleSource, ModuleDescriptor, | ||
18 | nameres::{ItemMap, InputModuleItems, FileItems} | ||
19 | }, | ||
17 | input::SourceRootId, | 20 | input::SourceRootId, |
18 | loc2id::IdDatabase, | 21 | loc2id::{IdDatabase, DefId, DefLoc}, |
19 | syntax_ptr::LocalSyntaxPtr, | 22 | syntax_ptr::LocalSyntaxPtr, |
20 | Cancelable, | 23 | Cancelable, |
21 | }; | 24 | }; |
@@ -67,6 +70,25 @@ salsa::query_group! { | |||
67 | } | 70 | } |
68 | } | 71 | } |
69 | 72 | ||
73 | pub(crate) enum Def { | ||
74 | Module(ModuleDescriptor), | ||
75 | Item, | ||
76 | } | ||
77 | |||
78 | impl DefId { | ||
79 | pub(crate) fn resolve(self, db: &impl DescriptorDatabase) -> Cancelable<Def> { | ||
80 | let loc = db.id_maps().def_loc(self); | ||
81 | let res = match loc { | ||
82 | DefLoc::Module { id, source_root } => { | ||
83 | let descr = ModuleDescriptor::new(db, source_root, id)?; | ||
84 | Def::Module(descr) | ||
85 | } | ||
86 | DefLoc::Item { .. } => Def::Item, | ||
87 | }; | ||
88 | Ok(res) | ||
89 | } | ||
90 | } | ||
91 | |||
70 | #[derive(Debug)] | 92 | #[derive(Debug)] |
71 | pub struct ReferenceDescriptor { | 93 | pub struct ReferenceDescriptor { |
72 | pub range: TextRange, | 94 | pub range: TextRange, |
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 764e19ce0..78911d5d9 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs | |||
@@ -77,7 +77,7 @@ impl ModuleDescriptor { | |||
77 | Ok(res) | 77 | Ok(res) |
78 | } | 78 | } |
79 | 79 | ||
80 | fn new( | 80 | pub(super) fn new( |
81 | db: &impl DescriptorDatabase, | 81 | db: &impl DescriptorDatabase, |
82 | source_root_id: SourceRootId, | 82 | source_root_id: SourceRootId, |
83 | module_id: ModuleId, | 83 | module_id: ModuleId, |
@@ -132,6 +132,14 @@ impl ModuleDescriptor { | |||
132 | Some(link.name(&self.tree)) | 132 | Some(link.name(&self.tree)) |
133 | } | 133 | } |
134 | 134 | ||
135 | pub fn def_id(&self, db: &impl DescriptorDatabase) -> DefId { | ||
136 | let def_loc = DefLoc::Module { | ||
137 | id: self.module_id, | ||
138 | source_root: self.source_root_id, | ||
139 | }; | ||
140 | db.id_maps().def_id(def_loc) | ||
141 | } | ||
142 | |||
135 | /// Finds a child module with the specified name. | 143 | /// Finds a child module with the specified name. |
136 | pub fn child(&self, name: &str) -> Option<ModuleDescriptor> { | 144 | pub fn child(&self, name: &str) -> Option<ModuleDescriptor> { |
137 | let child_id = self.module_id.child(&self.tree, name)?; | 145 | let child_id = self.module_id.child(&self.tree, name)?; |
@@ -152,23 +160,23 @@ impl ModuleDescriptor { | |||
152 | &self, | 160 | &self, |
153 | db: &impl DescriptorDatabase, | 161 | db: &impl DescriptorDatabase, |
154 | path: Path, | 162 | path: Path, |
155 | ) -> Cancelable<Option<ModuleDescriptor>> { | 163 | ) -> Cancelable<Option<DefId>> { |
156 | let mut curr = match path.kind { | 164 | let mut curr = match path.kind { |
157 | PathKind::Crate => self.crate_root(), | 165 | PathKind::Crate => self.crate_root(), |
158 | PathKind::Self_ | PathKind::Plain => self.clone(), | 166 | PathKind::Self_ | PathKind::Plain => self.clone(), |
159 | PathKind::Super => ctry!(self.parent()), | 167 | PathKind::Super => ctry!(self.parent()), |
160 | }; | 168 | } |
169 | .def_id(db); | ||
161 | 170 | ||
162 | let segments = path.segments; | 171 | let segments = path.segments; |
163 | for name in segments { | 172 | for name in segments.iter() { |
164 | let scope = curr.scope(db)?; | 173 | let module = match db.id_maps().def_loc(curr) { |
165 | let def_id = ctry!(ctry!(scope.get(&name)).def_id); | ||
166 | curr = match db.id_maps().def_loc(def_id) { | ||
167 | DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?, | 174 | DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?, |
168 | _ => return Ok(None), | 175 | _ => return Ok(None), |
169 | }; | 176 | }; |
177 | let scope = module.scope(db)?; | ||
178 | curr = ctry!(ctry!(scope.get(&name)).def_id); | ||
170 | } | 179 | } |
171 | |||
172 | Ok(Some(curr)) | 180 | Ok(Some(curr)) |
173 | } | 181 | } |
174 | 182 | ||