diff options
-rw-r--r-- | crates/ra_analysis/src/completion/mod.rs | 14 | ||||
-rw-r--r-- | crates/ra_analysis/src/completion/reference_completion.rs | 23 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 17 |
3 files changed, 36 insertions, 18 deletions
diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs index a8a752fc7..8034060de 100644 --- a/crates/ra_analysis/src/completion/mod.rs +++ b/crates/ra_analysis/src/completion/mod.rs | |||
@@ -221,6 +221,20 @@ mod tests { | |||
221 | } | 221 | } |
222 | 222 | ||
223 | #[test] | 223 | #[test] |
224 | fn test_completion_self_path() { | ||
225 | check_scope_completion( | ||
226 | r" | ||
227 | use self::m::B<|>; | ||
228 | |||
229 | mod m { | ||
230 | struct Bar; | ||
231 | } | ||
232 | ", | ||
233 | r#"[CompletionItem { label: "Bar", lookup: None, snippet: None }]"#, | ||
234 | ); | ||
235 | } | ||
236 | |||
237 | #[test] | ||
224 | fn test_completion_mod_scope_nested() { | 238 | fn test_completion_mod_scope_nested() { |
225 | check_scope_completion( | 239 | check_scope_completion( |
226 | r" | 240 | r" |
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index a96570415..d301a3c02 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs | |||
@@ -13,7 +13,7 @@ use crate::{ | |||
13 | descriptors::{ | 13 | descriptors::{ |
14 | module::{ModuleDescriptor}, | 14 | module::{ModuleDescriptor}, |
15 | function::FnScopes, | 15 | function::FnScopes, |
16 | Path, PathKind, | 16 | Path, |
17 | }, | 17 | }, |
18 | Cancelable | 18 | Cancelable |
19 | }; | 19 | }; |
@@ -148,9 +148,13 @@ fn complete_path( | |||
148 | acc: &mut Vec<CompletionItem>, | 148 | acc: &mut Vec<CompletionItem>, |
149 | db: &RootDatabase, | 149 | db: &RootDatabase, |
150 | module: &ModuleDescriptor, | 150 | module: &ModuleDescriptor, |
151 | path: Path, | 151 | mut path: Path, |
152 | ) -> Cancelable<()> { | 152 | ) -> Cancelable<()> { |
153 | let target_module = match find_target_module(module, path) { | 153 | if path.segments.is_empty() { |
154 | return Ok(()); | ||
155 | } | ||
156 | path.segments.pop(); | ||
157 | let target_module = match module.resolve_path(path) { | ||
154 | None => return Ok(()), | 158 | None => return Ok(()), |
155 | Some(it) => it, | 159 | Some(it) => it, |
156 | }; | 160 | }; |
@@ -167,19 +171,6 @@ fn complete_path( | |||
167 | Ok(()) | 171 | Ok(()) |
168 | } | 172 | } |
169 | 173 | ||
170 | fn find_target_module(module: &ModuleDescriptor, path: Path) -> Option<ModuleDescriptor> { | ||
171 | if path.kind != PathKind::Crate { | ||
172 | return None; | ||
173 | } | ||
174 | let mut segments = path.segments; | ||
175 | segments.pop(); | ||
176 | let mut target_module = module.crate_root(); | ||
177 | for name in segments { | ||
178 | target_module = target_module.child(&name)?; | ||
179 | } | ||
180 | Some(target_module) | ||
181 | } | ||
182 | |||
183 | fn complete_mod_item_snippets(acc: &mut Vec<CompletionItem>) { | 174 | fn complete_mod_item_snippets(acc: &mut Vec<CompletionItem>) { |
184 | acc.push(CompletionItem { | 175 | acc.push(CompletionItem { |
185 | label: "tfn".to_string(), | 176 | label: "tfn".to_string(), |
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index cfdffcdbc..a7e41e3db 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs | |||
@@ -14,11 +14,11 @@ use relative_path::RelativePathBuf; | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId, FilePosition, Cancelable, | 16 | db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId, FilePosition, Cancelable, |
17 | descriptors::DescriptorDatabase, | 17 | descriptors::{Path, PathKind, DescriptorDatabase}, |
18 | input::SourceRootId | 18 | input::SourceRootId |
19 | }; | 19 | }; |
20 | 20 | ||
21 | pub(crate) use self::{nameres::ModuleScope}; | 21 | pub(crate) use self::nameres::ModuleScope; |
22 | 22 | ||
23 | /// `ModuleDescriptor` is API entry point to get all the information | 23 | /// `ModuleDescriptor` is API entry point to get all the information |
24 | /// about a particular module. | 24 | /// about a particular module. |
@@ -131,6 +131,19 @@ impl ModuleDescriptor { | |||
131 | Ok(res) | 131 | Ok(res) |
132 | } | 132 | } |
133 | 133 | ||
134 | pub(crate) fn resolve_path(&self, path: Path) -> Option<ModuleDescriptor> { | ||
135 | let mut curr = match path.kind { | ||
136 | PathKind::Crate => self.crate_root(), | ||
137 | PathKind::Self_ | PathKind::Plain => self.clone(), | ||
138 | PathKind::Super => self.parent()?, | ||
139 | }; | ||
140 | let segments = path.segments; | ||
141 | for name in segments { | ||
142 | curr = curr.child(&name)?; | ||
143 | } | ||
144 | Some(curr) | ||
145 | } | ||
146 | |||
134 | pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> { | 147 | pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> { |
135 | self.module_id.problems(&self.tree, db) | 148 | self.module_id.problems(&self.tree, db) |
136 | } | 149 | } |