aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_analysis/src/descriptors/function/mod.rs2
-rw-r--r--crates/ra_analysis/src/descriptors/function/scope.rs4
-rw-r--r--crates/ra_analysis/src/imp.rs30
-rw-r--r--crates/ra_analysis/src/syntax_ptr.rs4
-rw-r--r--crates/ra_editor/src/lib.rs10
-rw-r--r--crates/ra_editor/src/scope/fn_scope.rs73
-rw-r--r--crates/ra_editor/src/scope/mod.rs2
7 files changed, 31 insertions, 94 deletions
diff --git a/crates/ra_analysis/src/descriptors/function/mod.rs b/crates/ra_analysis/src/descriptors/function/mod.rs
index 687413ddc..bb68b0ce7 100644
--- a/crates/ra_analysis/src/descriptors/function/mod.rs
+++ b/crates/ra_analysis/src/descriptors/function/mod.rs
@@ -10,7 +10,7 @@ use crate::{
10 syntax_ptr::SyntaxPtr 10 syntax_ptr::SyntaxPtr
11}; 11};
12 12
13pub(crate) use self::scope::FnScopes; 13pub(crate) use self::scope::{FnScopes, resolve_local_name};
14 14
15 15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/crates/ra_analysis/src/descriptors/function/scope.rs b/crates/ra_analysis/src/descriptors/function/scope.rs
index 5333a0a3b..d9929414c 100644
--- a/crates/ra_analysis/src/descriptors/function/scope.rs
+++ b/crates/ra_analysis/src/descriptors/function/scope.rs
@@ -1,4 +1,4 @@
1use rustc_hash::FxHashMap; 1use rustc_hash::{FxHashMap, FxHashSet};
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 algo::generate, 4 algo::generate,
@@ -261,8 +261,6 @@ pub fn resolve_local_name<'a>(
261 name_ref: ast::NameRef, 261 name_ref: ast::NameRef,
262 scopes: &'a FnScopes, 262 scopes: &'a FnScopes,
263) -> Option<&'a ScopeEntry> { 263) -> Option<&'a ScopeEntry> {
264 use rustc_hash::FxHashSet;
265
266 let mut shadowed = FxHashSet::default(); 264 let mut shadowed = FxHashSet::default();
267 let ret = scopes 265 let ret = scopes
268 .scope_chain(name_ref.syntax()) 266 .scope_chain(name_ref.syntax())
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 49b693ae8..6473a1dbc 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -3,7 +3,7 @@ use std::{
3 sync::Arc, 3 sync::Arc,
4}; 4};
5 5
6use ra_editor::{self, find_node_at_offset, resolve_local_name, FileSymbol, LineIndex, LocalEdit, CompletionItem}; 6use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit, CompletionItem};
7use ra_syntax::{ 7use ra_syntax::{
8 ast::{self, ArgListOwner, Expr, NameOwner}, 8 ast::{self, ArgListOwner, Expr, NameOwner},
9 AstNode, File, SmolStr, 9 AstNode, File, SmolStr,
@@ -21,10 +21,13 @@ use crate::{
21 self, SyntaxDatabase, FileSyntaxQuery, 21 self, SyntaxDatabase, FileSyntaxQuery,
22 }, 22 },
23 input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE}, 23 input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE},
24 descriptors::DescriptorDatabase, 24 descriptors::{
25 descriptors::module::{ModuleTree, Problem}, 25 DescriptorDatabase,
26 descriptors::function::{FnDescriptor}, 26 module::{ModuleTree, Problem},
27 function::{FnDescriptor, FnId},
28 },
27 symbol_index::SymbolIndex, 29 symbol_index::SymbolIndex,
30 syntax_ptr::SyntaxPtrDatabase,
28 CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position, 31 CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position,
29 Query, SourceChange, SourceFileEdit, Cancelable, 32 Query, SourceChange, SourceFileEdit, Cancelable,
30}; 33};
@@ -272,7 +275,7 @@ impl AnalysisImpl {
272 let syntax = file.syntax(); 275 let syntax = file.syntax();
273 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { 276 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
274 // First try to resolve the symbol locally 277 // First try to resolve the symbol locally
275 return if let Some((name, range)) = resolve_local_name(name_ref) { 278 return if let Some((name, range)) = resolve_local_name(&self.db, file_id, name_ref) {
276 let mut vec = vec![]; 279 let mut vec = vec![];
277 vec.push(( 280 vec.push((
278 file_id, 281 file_id,
@@ -326,7 +329,7 @@ impl AnalysisImpl {
326 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { 329 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
327 330
328 // We are only handing local references for now 331 // We are only handing local references for now
329 if let Some(resolved) = resolve_local_name(name_ref) { 332 if let Some(resolved) = resolve_local_name(&self.db, file_id, name_ref) {
330 333
331 ret.push((file_id, resolved.1)); 334 ret.push((file_id, resolved.1));
332 335
@@ -334,7 +337,7 @@ impl AnalysisImpl {
334 337
335 let refs : Vec<_> = fn_def.syntax().descendants() 338 let refs : Vec<_> = fn_def.syntax().descendants()
336 .filter_map(ast::NameRef::cast) 339 .filter_map(ast::NameRef::cast)
337 .filter(|&n: &ast::NameRef| resolve_local_name(n) == Some(resolved.clone())) 340 .filter(|&n: &ast::NameRef| resolve_local_name(&self.db, file_id, n) == Some(resolved.clone()))
338 .collect(); 341 .collect();
339 342
340 for r in refs { 343 for r in refs {
@@ -598,3 +601,16 @@ impl<'a> FnCallNode<'a> {
598 } 601 }
599 } 602 }
600} 603}
604
605fn resolve_local_name(
606 db: &db::RootDatabase,
607 file_id: FileId,
608 name_ref: ast::NameRef,
609) -> Option<(SmolStr, TextRange)> {
610 let fn_def = name_ref.syntax().ancestors().find_map(ast::FnDef::cast)?;
611 let fn_id = FnId::new(file_id, fn_def);
612 let scopes = db.fn_scopes(fn_id);
613 let scope_entry = crate::descriptors::function::resolve_local_name(name_ref, &scopes)?;
614 let syntax = db.resolve_syntax_ptr(scope_entry.ptr().into_global(file_id));
615 Some((scope_entry.name().clone(), syntax.range()))
616}
diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs
index aee214318..563a010d7 100644
--- a/crates/ra_analysis/src/syntax_ptr.rs
+++ b/crates/ra_analysis/src/syntax_ptr.rs
@@ -84,6 +84,10 @@ impl LocalSyntaxPtr {
84 .unwrap_or_else(|| panic!("can't resovle local ptr to SyntaxNode: {:?}", self)) 84 .unwrap_or_else(|| panic!("can't resovle local ptr to SyntaxNode: {:?}", self))
85 } 85 }
86 } 86 }
87
88 pub(crate) fn into_global(self, file_id: FileId) -> SyntaxPtr {
89 SyntaxPtr { file_id, local: self}
90 }
87} 91}
88 92
89 93
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs
index b73eb4ac7..ddcb6c6a2 100644
--- a/crates/ra_editor/src/lib.rs
+++ b/crates/ra_editor/src/lib.rs
@@ -151,15 +151,7 @@ pub fn find_node_at_offset<'a, N: AstNode<'a>>(
151 leaf.ancestors().filter_map(N::cast).next() 151 leaf.ancestors().filter_map(N::cast).next()
152} 152}
153 153
154pub fn resolve_local_name( 154
155 name_ref: ast::NameRef,
156) -> Option<(SmolStr, TextRange)> {
157 let fn_def = name_ref.syntax().ancestors().find_map(ast::FnDef::cast)?;
158 let scopes = scope::FnScopes::new(fn_def);
159 let scope_entry = scope::resolve_local_name(name_ref, &scopes)?;
160 let name = scope_entry.ast().name()?;
161 Some((scope_entry.name(), name.syntax().range()))
162}
163 155
164#[cfg(test)] 156#[cfg(test)]
165mod tests { 157mod tests {
diff --git a/crates/ra_editor/src/scope/fn_scope.rs b/crates/ra_editor/src/scope/fn_scope.rs
index f5c113fd9..4cb1f077c 100644
--- a/crates/ra_editor/src/scope/fn_scope.rs
+++ b/crates/ra_editor/src/scope/fn_scope.rs
@@ -258,22 +258,6 @@ struct ScopeData {
258 entries: Vec<ScopeEntry>, 258 entries: Vec<ScopeEntry>,
259} 259}
260 260
261pub fn resolve_local_name<'a>(
262 name_ref: ast::NameRef,
263 scopes: &'a FnScopes,
264) -> Option<&'a ScopeEntry> {
265 use rustc_hash::FxHashSet;
266
267 let mut shadowed = FxHashSet::default();
268 let ret = scopes
269 .scope_chain(name_ref.syntax())
270 .flat_map(|scope| scopes.entries(scope).iter())
271 .filter(|entry| shadowed.insert(entry.name()))
272 .filter(|entry| entry.name() == name_ref.text())
273 .nth(0);
274 ret
275}
276
277#[cfg(test)] 261#[cfg(test)]
278mod tests { 262mod tests {
279 use super::*; 263 use super::*;
@@ -376,61 +360,4 @@ mod tests {
376 &["x"], 360 &["x"],
377 ); 361 );
378 } 362 }
379
380 fn do_check_local_name(code: &str, expected_offset: u32) {
381 let (off, code) = extract_offset(code);
382 let file = File::parse(&code);
383 let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
384 let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
385
386 let scopes = FnScopes::new(fn_def);
387
388 let local_name = resolve_local_name(name_ref, &scopes)
389 .unwrap()
390 .ast()
391 .name()
392 .unwrap();
393 let expected_name =
394 find_node_at_offset::<ast::Name>(file.syntax(), expected_offset.into()).unwrap();
395 assert_eq!(local_name.syntax().range(), expected_name.syntax().range());
396 }
397
398 #[test]
399 fn test_resolve_local_name() {
400 do_check_local_name(
401 r#"
402 fn foo(x: i32, y: u32) {
403 {
404 let z = x * 2;
405 }
406 {
407 let t = x<|> * 3;
408 }
409 }"#,
410 21,
411 );
412 }
413
414 #[test]
415 fn test_resolve_local_name_declaration() {
416 do_check_local_name(
417 r#"
418 fn foo(x: String) {
419 let x : &str = &x<|>;
420 }"#,
421 21,
422 );
423 }
424
425 #[test]
426 fn test_resolve_local_name_shadow() {
427 do_check_local_name(
428 r"
429 fn foo(x: String) {
430 let x : &str = &x;
431 x<|>
432 }",
433 46,
434 );
435 }
436} 363}
diff --git a/crates/ra_editor/src/scope/mod.rs b/crates/ra_editor/src/scope/mod.rs
index cc2d49392..483f5e63c 100644
--- a/crates/ra_editor/src/scope/mod.rs
+++ b/crates/ra_editor/src/scope/mod.rs
@@ -2,6 +2,6 @@ mod fn_scope;
2mod mod_scope; 2mod mod_scope;
3 3
4pub use self::{ 4pub use self::{
5 fn_scope::{resolve_local_name, FnScopes}, 5 fn_scope::{FnScopes},
6 mod_scope::ModuleScope, 6 mod_scope::ModuleScope,
7}; 7};