aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_analysis/src/imp.rs34
-rw-r--r--crates/ra_hir/src/function/scope.rs24
-rw-r--r--crates/ra_hir/src/source_binder.rs23
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 @@
1use rustc_hash::{FxHashMap, FxHashSet}; 1use rustc_hash::{FxHashMap, FxHashSet};
2 2
3use ra_syntax::{ 3use 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
10use crate::{ 10use crate::{
11 arena::{Arena, Id}, 11 arena::{Arena, Id},
12 Name, AsName,
12}; 13};
13 14
14pub(crate) type ScopeId = Id<ScopeData>; 15pub(crate) type ScopeId = Id<ScopeData>;
@@ -22,7 +23,7 @@ pub struct FnScopes {
22 23
23#[derive(Debug, PartialEq, Eq)] 24#[derive(Debug, PartialEq, Eq)]
24pub struct ScopeEntry { 25pub 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
171impl ScopeEntry { 173impl 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 {
334mod tests { 336mod 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 @@
8use ra_db::{FileId, FilePosition, Cancelable}; 8use ra_db::{FileId, FilePosition, Cancelable};
9use ra_editor::find_node_at_offset; 9use ra_editor::find_node_at_offset;
10use ra_syntax::{ 10use ra_syntax::{
11 ast::{self, AstNode}, 11 ast::{self, AstNode, NameOwner},
12 SyntaxNodeRef, 12 SyntaxNodeRef,
13}; 13};
14 14
15use crate::{ 15use 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.
28pub 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.
28pub fn module_from_position( 47pub fn module_from_position(
29 db: &impl HirDatabase, 48 db: &impl HirDatabase,