diff options
-rw-r--r-- | crates/ra_analysis/src/descriptors/function/mod.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/function/scope.rs | 4 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 30 | ||||
-rw-r--r-- | crates/ra_analysis/src/syntax_ptr.rs | 4 | ||||
-rw-r--r-- | crates/ra_editor/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_editor/src/scope/fn_scope.rs | 73 | ||||
-rw-r--r-- | crates/ra_editor/src/scope/mod.rs | 2 |
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 | ||
13 | pub(crate) use self::scope::FnScopes; | 13 | pub(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 @@ | |||
1 | use rustc_hash::FxHashMap; | 1 | use rustc_hash::{FxHashMap, FxHashSet}; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use 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 | ||
6 | use ra_editor::{self, find_node_at_offset, resolve_local_name, FileSymbol, LineIndex, LocalEdit, CompletionItem}; | 6 | use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit, CompletionItem}; |
7 | use ra_syntax::{ | 7 | use 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 | |||
605 | fn 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 | ||
154 | pub 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)] |
165 | mod tests { | 157 | mod 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 | ||
261 | pub 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)] |
278 | mod tests { | 262 | mod 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; | |||
2 | mod mod_scope; | 2 | mod mod_scope; |
3 | 3 | ||
4 | pub use self::{ | 4 | pub use self::{ |
5 | fn_scope::{resolve_local_name, FnScopes}, | 5 | fn_scope::{FnScopes}, |
6 | mod_scope::ModuleScope, | 6 | mod_scope::ModuleScope, |
7 | }; | 7 | }; |