diff options
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 34 | ||||
-rw-r--r-- | crates/ra_hir/src/function/scope.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 23 |
3 files changed, 51 insertions, 30 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 38a5c1a7d..0471a2fca 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -243,7 +243,7 @@ impl AnalysisImpl { | |||
243 | rr.add_resolution( | 243 | rr.add_resolution( |
244 | position.file_id, | 244 | position.file_id, |
245 | FileSymbol { | 245 | FileSymbol { |
246 | name: entry.name().clone(), | 246 | name: entry.name().to_string().into(), |
247 | node_range: entry.ptr().range(), | 247 | node_range: entry.ptr().range(), |
248 | kind: NAME, | 248 | kind: NAME, |
249 | }, | 249 | }, |
@@ -261,23 +261,21 @@ impl AnalysisImpl { | |||
261 | let mut rr = ReferenceResolution::new(name.syntax().range()); | 261 | let mut rr = ReferenceResolution::new(name.syntax().range()); |
262 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 262 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
263 | if module.has_semi() { | 263 | if module.has_semi() { |
264 | let parent_module = | 264 | if let Some(child_module) = |
265 | source_binder::module_from_file_id(&*self.db, position.file_id)?; | 265 | source_binder::module_from_declaration(&*self.db, position.file_id, module)? |
266 | let child_name = module.name(); | 266 | { |
267 | match (parent_module, child_name) { | 267 | let file_id = child_module.source().file_id(); |
268 | (Some(parent_module), Some(child_name)) => { | 268 | let name = match child_module.name() { |
269 | if let Some(child) = parent_module.child(&child_name.text()) { | 269 | Some(name) => name.to_string().into(), |
270 | let file_id = child.source().file_id(); | 270 | None => "".into(), |
271 | let symbol = FileSymbol { | 271 | }; |
272 | name: child_name.text(), | 272 | let symbol = FileSymbol { |
273 | node_range: TextRange::offset_len(0.into(), 0.into()), | 273 | name, |
274 | kind: MODULE, | 274 | node_range: TextRange::offset_len(0.into(), 0.into()), |
275 | }; | 275 | kind: MODULE, |
276 | rr.add_resolution(file_id, symbol); | 276 | }; |
277 | return Ok(Some(rr)); | 277 | rr.add_resolution(file_id, symbol); |
278 | } | 278 | return Ok(Some(rr)); |
279 | } | ||
280 | _ => (), | ||
281 | } | 279 | } |
282 | } | 280 | } |
283 | } | 281 | } |
diff --git a/crates/ra_hir/src/function/scope.rs b/crates/ra_hir/src/function/scope.rs index a1a580979..3e4cfad0c 100644 --- a/crates/ra_hir/src/function/scope.rs +++ b/crates/ra_hir/src/function/scope.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use rustc_hash::{FxHashMap, FxHashSet}; | 1 | use rustc_hash::{FxHashMap, FxHashSet}; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | AstNode, SmolStr, SyntaxNodeRef, TextUnit, TextRange, | 4 | AstNode, SyntaxNodeRef, TextUnit, TextRange, |
5 | algo::generate, | 5 | algo::generate, |
6 | ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, | 6 | ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, |
7 | }; | 7 | }; |
@@ -9,6 +9,7 @@ use ra_db::LocalSyntaxPtr; | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | arena::{Arena, Id}, | 11 | arena::{Arena, Id}, |
12 | Name, AsName, | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | pub(crate) type ScopeId = Id<ScopeData>; | 15 | pub(crate) type ScopeId = Id<ScopeData>; |
@@ -22,7 +23,7 @@ pub struct FnScopes { | |||
22 | 23 | ||
23 | #[derive(Debug, PartialEq, Eq)] | 24 | #[derive(Debug, PartialEq, Eq)] |
24 | pub struct ScopeEntry { | 25 | pub struct ScopeEntry { |
25 | name: SmolStr, | 26 | name: Name, |
26 | ptr: LocalSyntaxPtr, | 27 | ptr: LocalSyntaxPtr, |
27 | } | 28 | } |
28 | 29 | ||
@@ -101,11 +102,12 @@ impl FnScopes { | |||
101 | 102 | ||
102 | pub fn resolve_local_name<'a>(&'a self, name_ref: ast::NameRef) -> Option<&'a ScopeEntry> { | 103 | pub fn resolve_local_name<'a>(&'a self, name_ref: ast::NameRef) -> Option<&'a ScopeEntry> { |
103 | let mut shadowed = FxHashSet::default(); | 104 | let mut shadowed = FxHashSet::default(); |
105 | let name = name_ref.as_name(); | ||
104 | let ret = self | 106 | let ret = self |
105 | .scope_chain(name_ref.syntax()) | 107 | .scope_chain(name_ref.syntax()) |
106 | .flat_map(|scope| self.entries(scope).iter()) | 108 | .flat_map(|scope| self.entries(scope).iter()) |
107 | .filter(|entry| shadowed.insert(entry.name())) | 109 | .filter(|entry| shadowed.insert(entry.name())) |
108 | .filter(|entry| entry.name() == &name_ref.text()) | 110 | .filter(|entry| entry.name() == &name) |
109 | .nth(0); | 111 | .nth(0); |
110 | ret | 112 | ret |
111 | } | 113 | } |
@@ -170,14 +172,14 @@ impl FnScopes { | |||
170 | 172 | ||
171 | impl ScopeEntry { | 173 | impl ScopeEntry { |
172 | fn new(pat: ast::BindPat) -> Option<ScopeEntry> { | 174 | fn new(pat: ast::BindPat) -> Option<ScopeEntry> { |
173 | let name = pat.name()?; | 175 | let name = pat.name()?.as_name(); |
174 | let res = ScopeEntry { | 176 | let res = ScopeEntry { |
175 | name: name.text(), | 177 | name, |
176 | ptr: LocalSyntaxPtr::new(pat.syntax()), | 178 | ptr: LocalSyntaxPtr::new(pat.syntax()), |
177 | }; | 179 | }; |
178 | Some(res) | 180 | Some(res) |
179 | } | 181 | } |
180 | pub fn name(&self) -> &SmolStr { | 182 | pub fn name(&self) -> &Name { |
181 | &self.name | 183 | &self.name |
182 | } | 184 | } |
183 | pub fn ptr(&self) -> LocalSyntaxPtr { | 185 | pub fn ptr(&self) -> LocalSyntaxPtr { |
@@ -334,7 +336,7 @@ pub struct ReferenceDescriptor { | |||
334 | mod tests { | 336 | mod tests { |
335 | use ra_editor::find_node_at_offset; | 337 | use ra_editor::find_node_at_offset; |
336 | use ra_syntax::SourceFileNode; | 338 | use ra_syntax::SourceFileNode; |
337 | use test_utils::extract_offset; | 339 | use test_utils::{extract_offset, assert_eq_text}; |
338 | 340 | ||
339 | use super::*; | 341 | use super::*; |
340 | 342 | ||
@@ -355,9 +357,11 @@ mod tests { | |||
355 | let actual = scopes | 357 | let actual = scopes |
356 | .scope_chain(marker.syntax()) | 358 | .scope_chain(marker.syntax()) |
357 | .flat_map(|scope| scopes.entries(scope)) | 359 | .flat_map(|scope| scopes.entries(scope)) |
358 | .map(|it| it.name()) | 360 | .map(|it| it.name().to_string()) |
359 | .collect::<Vec<_>>(); | 361 | .collect::<Vec<_>>() |
360 | assert_eq!(actual.as_slice(), expected); | 362 | .join("\n"); |
363 | let expected = expected.join("\n"); | ||
364 | assert_eq_text!(&actual, &expected); | ||
361 | } | 365 | } |
362 | 366 | ||
363 | #[test] | 367 | #[test] |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index a0165aef2..a0d1daf71 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -8,14 +8,14 @@ | |||
8 | use ra_db::{FileId, FilePosition, Cancelable}; | 8 | use ra_db::{FileId, FilePosition, Cancelable}; |
9 | use ra_editor::find_node_at_offset; | 9 | use ra_editor::find_node_at_offset; |
10 | use ra_syntax::{ | 10 | use ra_syntax::{ |
11 | ast::{self, AstNode}, | 11 | ast::{self, AstNode, NameOwner}, |
12 | SyntaxNodeRef, | 12 | SyntaxNodeRef, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Module, Function, SourceItemId, | 16 | HirDatabase, Module, Function, SourceItemId, |
17 | module::ModuleSource, | 17 | module::ModuleSource, |
18 | DefKind, DefLoc | 18 | DefKind, DefLoc, AsName, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | /// Locates the module by `FileId`. Picks topmost module in the file. | 21 | /// Locates the module by `FileId`. Picks topmost module in the file. |
@@ -24,6 +24,25 @@ pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable | |||
24 | module_from_source(db, module_source) | 24 | module_from_source(db, module_source) |
25 | } | 25 | } |
26 | 26 | ||
27 | /// Locates the child module by `mod child;` declaration. | ||
28 | pub fn module_from_declaration( | ||
29 | db: &impl HirDatabase, | ||
30 | file_id: FileId, | ||
31 | decl: ast::Module, | ||
32 | ) -> Cancelable<Option<Module>> { | ||
33 | let parent_module = module_from_file_id(db, file_id)?; | ||
34 | let child_name = decl.name(); | ||
35 | match (parent_module, child_name) { | ||
36 | (Some(parent_module), Some(child_name)) => { | ||
37 | if let Some(child) = parent_module.child(&child_name.as_name()) { | ||
38 | return Ok(Some(child)); | ||
39 | } | ||
40 | } | ||
41 | _ => (), | ||
42 | } | ||
43 | Ok(None) | ||
44 | } | ||
45 | |||
27 | /// Locates the module by position in the source code. | 46 | /// Locates the module by position in the source code. |
28 | pub fn module_from_position( | 47 | pub fn module_from_position( |
29 | db: &impl HirDatabase, | 48 | db: &impl HirDatabase, |