aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/references.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-10-24 12:17:03 +0100
committerGitHub <[email protected]>2019-10-24 12:17:03 +0100
commit95cf5c86fae3adf3bb38521905bf357450125709 (patch)
treedf21a3aec7f580d4c6a768ceee7a7d1f9351838e /crates/ra_ide_api/src/references.rs
parent29a31a663914ef0bfe36e7ff45a58762c9313086 (diff)
parent4529da906db7f18aaf384c079332e4ea12c82d55 (diff)
Merge #2059
2059: for highlighting, search only the current file r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_ide_api/src/references.rs')
-rw-r--r--crates/ra_ide_api/src/references.rs61
1 files changed, 52 insertions, 9 deletions
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index 8200bd1ef..b5b1c9a16 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -27,6 +27,8 @@ pub(crate) use self::{
27 rename::rename, 27 rename::rename,
28}; 28};
29 29
30pub use self::search_scope::SearchScope;
31
30#[derive(Debug, Clone)] 32#[derive(Debug, Clone)]
31pub struct ReferenceSearchResult { 33pub struct ReferenceSearchResult {
32 declaration: NavigationTarget, 34 declaration: NavigationTarget,
@@ -67,6 +69,7 @@ impl IntoIterator for ReferenceSearchResult {
67pub(crate) fn find_all_refs( 69pub(crate) fn find_all_refs(
68 db: &RootDatabase, 70 db: &RootDatabase,
69 position: FilePosition, 71 position: FilePosition,
72 search_scope: Option<SearchScope>,
70) -> Option<RangeInfo<ReferenceSearchResult>> { 73) -> Option<RangeInfo<ReferenceSearchResult>> {
71 let parse = db.parse(position.file_id); 74 let parse = db.parse(position.file_id);
72 let syntax = parse.tree().syntax().clone(); 75 let syntax = parse.tree().syntax().clone();
@@ -86,7 +89,15 @@ pub(crate) fn find_all_refs(
86 NameKind::GenericParam(_) => return None, 89 NameKind::GenericParam(_) => return None,
87 }; 90 };
88 91
89 let references = process_definition(db, def, name); 92 let search_scope = {
93 let base = def.search_scope(db);
94 match search_scope {
95 None => base,
96 Some(scope) => base.intersection(&scope),
97 }
98 };
99
100 let references = process_definition(db, def, name, search_scope);
90 101
91 Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references })) 102 Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references }))
92} 103}
@@ -107,11 +118,15 @@ fn find_name<'a>(
107 Some(RangeInfo::new(range, (name_ref.text().to_string(), def))) 118 Some(RangeInfo::new(range, (name_ref.text().to_string(), def)))
108} 119}
109 120
110fn process_definition(db: &RootDatabase, def: NameDefinition, name: String) -> Vec<FileRange> { 121fn process_definition(
122 db: &RootDatabase,
123 def: NameDefinition,
124 name: String,
125 scope: SearchScope,
126) -> Vec<FileRange> {
111 let _p = profile("process_definition"); 127 let _p = profile("process_definition");
112 128
113 let pat = name.as_str(); 129 let pat = name.as_str();
114 let scope = def.search_scope(db);
115 let mut refs = vec![]; 130 let mut refs = vec![];
116 131
117 for (file_id, search_range) in scope { 132 for (file_id, search_range) in scope {
@@ -144,8 +159,8 @@ fn process_definition(db: &RootDatabase, def: NameDefinition, name: String) -> V
144#[cfg(test)] 159#[cfg(test)]
145mod tests { 160mod tests {
146 use crate::{ 161 use crate::{
147 mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, 162 mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis},
148 ReferenceSearchResult, 163 ReferenceSearchResult, SearchScope,
149 }; 164 };
150 165
151 #[test] 166 #[test]
@@ -270,7 +285,7 @@ mod tests {
270 "#; 285 "#;
271 286
272 let (analysis, pos) = analysis_and_position(code); 287 let (analysis, pos) = analysis_and_position(code);
273 let refs = analysis.find_all_refs(pos).unwrap().unwrap(); 288 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
274 assert_eq!(refs.len(), 3); 289 assert_eq!(refs.len(), 3);
275 } 290 }
276 291
@@ -296,7 +311,7 @@ mod tests {
296 "#; 311 "#;
297 312
298 let (analysis, pos) = analysis_and_position(code); 313 let (analysis, pos) = analysis_and_position(code);
299 let refs = analysis.find_all_refs(pos).unwrap().unwrap(); 314 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
300 assert_eq!(refs.len(), 2); 315 assert_eq!(refs.len(), 2);
301 } 316 }
302 317
@@ -321,12 +336,40 @@ mod tests {
321 "#; 336 "#;
322 337
323 let (analysis, pos) = analysis_and_position(code); 338 let (analysis, pos) = analysis_and_position(code);
324 let refs = analysis.find_all_refs(pos).unwrap().unwrap(); 339 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
340 assert_eq!(refs.len(), 3);
341 }
342
343 #[test]
344 fn test_find_all_refs_with_scope() {
345 let code = r#"
346 //- /lib.rs
347 mod foo;
348 mod bar;
349
350 pub fn quux<|>() {}
351
352 //- /foo.rs
353 fn f() { super::quux(); }
354
355 //- /bar.rs
356 fn f() { super::quux(); }
357 "#;
358
359 let (mock, pos) = MockAnalysis::with_files_and_position(code);
360 let bar = mock.id_of("/bar.rs");
361 let analysis = mock.analysis();
362
363 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
325 assert_eq!(refs.len(), 3); 364 assert_eq!(refs.len(), 3);
365
366 let refs =
367 analysis.find_all_refs(pos, Some(SearchScope::single_file(bar))).unwrap().unwrap();
368 assert_eq!(refs.len(), 2);
326 } 369 }
327 370
328 fn get_all_refs(text: &str) -> ReferenceSearchResult { 371 fn get_all_refs(text: &str) -> ReferenceSearchResult {
329 let (analysis, position) = single_file_with_position(text); 372 let (analysis, position) = single_file_with_position(text);
330 analysis.find_all_refs(position).unwrap().unwrap() 373 analysis.find_all_refs(position, None).unwrap().unwrap()
331 } 374 }
332} 375}