aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
authorJeremy A. Kolb <[email protected]>2018-10-18 18:40:12 +0100
committerJeremy A. Kolb <[email protected]>2018-10-18 18:40:12 +0100
commit3746689e9ddea455d10a41d9fc3af33b22a3707d (patch)
tree04c4e94e40f5496d961ca2f3dc649da1dd84604e /crates/ra_analysis
parent2a704035f4b36a0db737f59a7c939d17656b516f (diff)
Implement Find All References for local variables
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/imp.rs32
-rw-r--r--crates/ra_analysis/src/lib.rs3
-rw-r--r--crates/ra_analysis/tests/tests.rs42
3 files changed, 77 insertions, 0 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index f1403cb5d..a67b1717a 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -257,6 +257,38 @@ impl AnalysisImpl {
257 vec![] 257 vec![]
258 } 258 }
259 259
260 pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, _token: &JobToken) -> Vec<(FileId, TextRange)> {
261 let root = self.root(file_id);
262 let file = root.syntax(file_id);
263 let syntax = file.syntax();
264
265 let mut ret = vec![];
266
267 // Find the symbol we are looking for
268 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
269
270 // We are only handing local references for now
271 if let Some(resolved) = resolve_local_name(&file, offset, name_ref) {
272
273 ret.push((file_id, resolved.1));
274
275 if let Some(fn_def) = find_node_at_offset::<ast::FnDef>(syntax, offset) {
276
277 let refs : Vec<_> = fn_def.syntax().descendants()
278 .filter_map(ast::NameRef::cast)
279 .filter(|n: &ast::NameRef| resolve_local_name(&file, n.syntax().range().start(), *n) == Some(resolved.clone()))
280 .collect();
281
282 for r in refs {
283 ret.push((file_id, r.syntax().range()));
284 }
285 }
286 }
287 }
288
289 ret
290 }
291
260 pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { 292 pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> {
261 let root = self.root(file_id); 293 let root = self.root(file_id);
262 let module_tree = root.module_tree(); 294 let module_tree = root.module_tree();
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 2eeacaabe..46cc0722b 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -217,6 +217,9 @@ impl Analysis {
217 self.imp 217 self.imp
218 .approximately_resolve_symbol(file_id, offset, token) 218 .approximately_resolve_symbol(file_id, offset, token)
219 } 219 }
220 pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, token: &JobToken) -> Vec<(FileId, TextRange)> {
221 self.imp.find_all_refs(file_id, offset, token)
222 }
220 pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { 223 pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> {
221 self.imp.parent_module(file_id) 224 self.imp.parent_module(file_id)
222 } 225 }
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs
index e0c637d65..0c2c69ea0 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/tests.rs
@@ -10,6 +10,8 @@ use std::sync::Arc;
10use ra_analysis::{ 10use ra_analysis::{
11 Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, FnDescriptor, JobHandle, 11 Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, FnDescriptor, JobHandle,
12}; 12};
13use ra_syntax::TextRange;
14
13use relative_path::{RelativePath, RelativePathBuf}; 15use relative_path::{RelativePath, RelativePathBuf};
14use rustc_hash::FxHashMap; 16use rustc_hash::FxHashMap;
15use test_utils::{assert_eq_dbg, extract_offset}; 17use test_utils::{assert_eq_dbg, extract_offset};
@@ -225,3 +227,43 @@ fn bar() {
225 assert_eq!(desc.ret_type, None); 227 assert_eq!(desc.ret_type, None);
226 assert_eq!(param, Some(1)); 228 assert_eq!(param, Some(1));
227} 229}
230
231fn get_all_refs(text: &str) -> Vec<(FileId, TextRange)> {
232 let (offset, code) = extract_offset(text);
233 let code = code.as_str();
234
235 let (_handle, token) = JobHandle::new();
236 let snap = analysis(&[("/lib.rs", code)]);
237
238 snap.find_all_refs(FileId(1), offset, &token)
239}
240
241#[test]
242fn test_find_all_refs_for_local() {
243 let code = r#"
244 fn main() {
245 let mut i = 1;
246 let j = 1;
247 i = i<|> + j;
248
249 {
250 i = 0;
251 }
252
253 i = 5;
254 }"#;
255
256 let refs = get_all_refs(code);
257 assert_eq!(refs.len(), 5);
258}
259
260#[test]
261fn test_find_all_refs_for_param_inside() {
262 let code = r#"
263 fn foo(i : u32) -> u32 {
264 i<|>
265 }"#;
266
267 let refs = get_all_refs(code);
268 assert_eq!(refs.len(), 2);
269} \ No newline at end of file