diff options
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r-- | crates/ra_analysis/src/descriptors/mod.rs | 57 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 13 | ||||
-rw-r--r-- | crates/ra_analysis/tests/tests.rs | 11 |
3 files changed, 77 insertions, 4 deletions
diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index 0c4991757..e27f8314a 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs | |||
@@ -5,16 +5,17 @@ use std::sync::Arc; | |||
5 | 5 | ||
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | SmolStr, | 7 | SmolStr, |
8 | ast::{FnDefNode}, | 8 | ast::{self, AstNode, FnDefNode}, |
9 | TextRange | ||
9 | }; | 10 | }; |
10 | 11 | ||
11 | use crate::{ | 12 | use crate::{ |
12 | FileId, Cancelable, | 13 | FileId, Cancelable, |
13 | db::SyntaxDatabase, | 14 | db::SyntaxDatabase, |
14 | descriptors::module::{ModuleTree, ModuleId, ModuleScope}, | 15 | descriptors::module::{ModuleTree, ModuleId, ModuleScope}, |
15 | descriptors::function::{FnId, FnScopes}, | 16 | descriptors::function::{FnId, FnScopes, resolve_local_name}, |
16 | input::SourceRootId, | 17 | input::SourceRootId, |
17 | syntax_ptr::SyntaxPtrDatabase, | 18 | syntax_ptr::{SyntaxPtrDatabase, LocalSyntaxPtr}, |
18 | }; | 19 | }; |
19 | 20 | ||
20 | 21 | ||
@@ -44,3 +45,53 @@ salsa::query_group! { | |||
44 | } | 45 | } |
45 | } | 46 | } |
46 | } | 47 | } |
48 | |||
49 | #[derive(Debug)] | ||
50 | pub struct ReferenceDescriptor { | ||
51 | pub range: TextRange, | ||
52 | pub name: String | ||
53 | } | ||
54 | |||
55 | #[derive(Debug)] | ||
56 | pub struct DeclarationDescriptor<'a> { | ||
57 | pat: ast::BindPat<'a>, | ||
58 | pub range: TextRange | ||
59 | } | ||
60 | |||
61 | impl<'a> DeclarationDescriptor<'a> { | ||
62 | pub fn new(pat: ast::BindPat) -> DeclarationDescriptor { | ||
63 | let range = pat.syntax().range(); | ||
64 | |||
65 | DeclarationDescriptor { | ||
66 | pat, | ||
67 | range | ||
68 | } | ||
69 | } | ||
70 | |||
71 | pub fn find_all_refs(&self) -> Vec<ReferenceDescriptor> { | ||
72 | let name_ptr = LocalSyntaxPtr::new(self.pat.syntax()); | ||
73 | |||
74 | let fn_def = match self.pat.syntax().ancestors().find_map(ast::FnDef::cast) { | ||
75 | Some(def) => def, | ||
76 | None => return Default::default() | ||
77 | }; | ||
78 | |||
79 | let fn_scopes = FnScopes::new(fn_def); | ||
80 | |||
81 | let refs : Vec<_> = fn_def.syntax().descendants() | ||
82 | .filter_map(ast::NameRef::cast) | ||
83 | .filter(|name_ref| { | ||
84 | match resolve_local_name(*name_ref, &fn_scopes) { | ||
85 | None => false, | ||
86 | Some(entry) => entry.ptr() == name_ptr, | ||
87 | } | ||
88 | }) | ||
89 | .map(|name_ref| ReferenceDescriptor { | ||
90 | name: name_ref.syntax().text().to_string(), | ||
91 | range : name_ref.syntax().range(), | ||
92 | }) | ||
93 | .collect(); | ||
94 | |||
95 | refs | ||
96 | } | ||
97 | } | ||
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index b3c094041..f950a7995 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | }, | 22 | }, |
23 | input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE}, | 23 | input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE}, |
24 | descriptors::{ | 24 | descriptors::{ |
25 | DescriptorDatabase, | 25 | DescriptorDatabase, DeclarationDescriptor, |
26 | module::{ModuleTree, Problem}, | 26 | module::{ModuleTree, Problem}, |
27 | function::{FnDescriptor, FnId}, | 27 | function::{FnDescriptor, FnId}, |
28 | }, | 28 | }, |
@@ -327,6 +327,17 @@ impl AnalysisImpl { | |||
327 | 327 | ||
328 | let mut ret = vec![]; | 328 | let mut ret = vec![]; |
329 | 329 | ||
330 | if let Some(binding) = find_node_at_offset::<ast::BindPat>(syntax, offset) { | ||
331 | let decl = DeclarationDescriptor::new(binding); | ||
332 | |||
333 | ret.push((file_id, decl.range)); | ||
334 | |||
335 | ret.extend(decl.find_all_refs().into_iter() | ||
336 | .map(|ref_desc| (file_id, ref_desc.range ))); | ||
337 | |||
338 | return ret; | ||
339 | } | ||
340 | |||
330 | // Find the symbol we are looking for | 341 | // Find the symbol we are looking for |
331 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { | 342 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { |
332 | 343 | ||
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs index 9e2478d9e..22d27cdbe 100644 --- a/crates/ra_analysis/tests/tests.rs +++ b/crates/ra_analysis/tests/tests.rs | |||
@@ -378,6 +378,17 @@ fn test_find_all_refs_for_param_inside() { | |||
378 | } | 378 | } |
379 | 379 | ||
380 | #[test] | 380 | #[test] |
381 | fn test_find_all_refs_for_fn_param() { | ||
382 | let code = r#" | ||
383 | fn foo(i<|> : u32) -> u32 { | ||
384 | i | ||
385 | }"#; | ||
386 | |||
387 | let refs = get_all_refs(code); | ||
388 | assert_eq!(refs.len(), 2); | ||
389 | } | ||
390 | |||
391 | #[test] | ||
381 | fn test_complete_crate_path() { | 392 | fn test_complete_crate_path() { |
382 | let (analysis, position) = analysis_and_position(" | 393 | let (analysis, position) = analysis_and_position(" |
383 | //- /lib.rs | 394 | //- /lib.rs |