aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/references/search_scope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/references/search_scope.rs')
-rw-r--r--crates/ra_ide_api/src/references/search_scope.rs81
1 files changed, 37 insertions, 44 deletions
diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide_api/src/references/search_scope.rs
index 8495a92a5..5cb69b8fc 100644
--- a/crates/ra_ide_api/src/references/search_scope.rs
+++ b/crates/ra_ide_api/src/references/search_scope.rs
@@ -1,72 +1,66 @@
1//! FIXME: write short doc here 1//! Generally, `search_scope` returns files that might contain references for the element.
2 2//! For `pub(crate)` things it's a crate, for `pub` things it's a crate and dependant crates.
3use std::collections::HashSet; 3//! In some cases, the location of the references is known to within a `TextRange`,
4//! e.g. for things like local variables.
4 5
5use hir::{DefWithBody, HasSource, ModuleSource}; 6use hir::{DefWithBody, HasSource, ModuleSource};
6use ra_db::{FileId, SourceDatabase, SourceDatabaseExt}; 7use ra_db::{FileId, SourceDatabase, SourceDatabaseExt};
7use ra_syntax::{AstNode, TextRange}; 8use ra_syntax::{AstNode, TextRange};
9use rustc_hash::FxHashSet;
8 10
9use crate::db::RootDatabase; 11use crate::db::RootDatabase;
10 12
11use super::{NameDefinition, NameKind}; 13use super::{NameDefinition, NameKind};
12 14
13impl NameDefinition { 15impl NameDefinition {
14 pub(crate) fn search_scope(&self, db: &RootDatabase) -> HashSet<(FileId, Option<TextRange>)> { 16 pub(crate) fn search_scope(&self, db: &RootDatabase) -> FxHashSet<(FileId, Option<TextRange>)> {
15 let module_src = self.container.definition_source(db); 17 let module_src = self.container.definition_source(db);
16 let file_id = module_src.file_id.original_file(db); 18 let file_id = module_src.file_id.original_file(db);
17 19
18 if let NameKind::Pat((def, _)) = self.kind { 20 if let NameKind::Pat((def, _)) = self.kind {
21 let mut res = FxHashSet::default();
19 let range = match def { 22 let range = match def {
20 DefWithBody::Function(f) => f.source(db).ast.syntax().text_range(), 23 DefWithBody::Function(f) => f.source(db).ast.syntax().text_range(),
21 DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(), 24 DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(),
22 DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(), 25 DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(),
23 }; 26 };
24 return [(file_id, Some(range))].iter().cloned().collect(); 27 res.insert((file_id, Some(range)));
28 return res;
25 } 29 }
26 30
27 if let Some(ref vis) = self.visibility { 31 let vis =
28 let vis = vis.syntax().to_string(); 32 self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or("".to_string());
29
30 // FIXME: add "pub(in path)"
31
32 if vis.as_str() == "pub(super)" {
33 if let Some(parent_module) = self.container.parent(db) {
34 let mut files = HashSet::new();
35 33
36 let parent_src = parent_module.definition_source(db); 34 if vis.as_str() == "pub(super)" {
37 let file_id = parent_src.file_id.original_file(db); 35 if let Some(parent_module) = self.container.parent(db) {
36 let mut files = FxHashSet::default();
37 let parent_src = parent_module.definition_source(db);
38 let file_id = parent_src.file_id.original_file(db);
38 39
39 match parent_src.ast { 40 match parent_src.ast {
40 ModuleSource::Module(m) => { 41 ModuleSource::Module(m) => {
41 let range = Some(m.syntax().text_range()); 42 let range = Some(m.syntax().text_range());
42 files.insert((file_id, range)); 43 files.insert((file_id, range));
43 } 44 }
44 ModuleSource::SourceFile(_) => { 45 ModuleSource::SourceFile(_) => {
45 files.insert((file_id, None)); 46 files.insert((file_id, None));
46 files.extend( 47 files.extend(parent_module.children(db).map(|m| {
47 parent_module 48 let src = m.definition_source(db);
48 .children(db) 49 (src.file_id.original_file(db), None)
49 .map(|m| { 50 }));
50 let src = m.definition_source(db);
51 (src.file_id.original_file(db), None)
52 })
53 .collect::<HashSet<_>>(),
54 );
55 }
56 } 51 }
57 return files;
58 } else {
59 let range = match module_src.ast {
60 ModuleSource::Module(m) => Some(m.syntax().text_range()),
61 ModuleSource::SourceFile(_) => None,
62 };
63 return [(file_id, range)].iter().cloned().collect();
64 } 52 }
53 return files;
65 } 54 }
55 }
66 56
57 if vis.as_str() != "" {
67 let source_root_id = db.file_source_root(file_id); 58 let source_root_id = db.file_source_root(file_id);
68 let source_root = db.source_root(source_root_id); 59 let source_root = db.source_root(source_root_id);
69 let mut files = source_root.walk().map(|id| (id.into(), None)).collect::<HashSet<_>>(); 60 let mut files =
61 source_root.walk().map(|id| (id.into(), None)).collect::<FxHashSet<_>>();
62
63 // FIXME: add "pub(in path)"
70 64
71 if vis.as_str() == "pub(crate)" { 65 if vis.as_str() == "pub(crate)" {
72 return files; 66 return files;
@@ -74,10 +68,8 @@ impl NameDefinition {
74 if vis.as_str() == "pub" { 68 if vis.as_str() == "pub" {
75 let krate = self.container.krate(db).unwrap(); 69 let krate = self.container.krate(db).unwrap();
76 let crate_graph = db.crate_graph(); 70 let crate_graph = db.crate_graph();
77
78 for crate_id in crate_graph.iter() { 71 for crate_id in crate_graph.iter() {
79 let mut crate_deps = crate_graph.dependencies(crate_id); 72 let mut crate_deps = crate_graph.dependencies(crate_id);
80
81 if crate_deps.any(|dep| dep.crate_id() == krate.crate_id()) { 73 if crate_deps.any(|dep| dep.crate_id() == krate.crate_id()) {
82 let root_file = crate_graph.crate_root(crate_id); 74 let root_file = crate_graph.crate_root(crate_id);
83 let source_root_id = db.file_source_root(root_file); 75 let source_root_id = db.file_source_root(root_file);
@@ -85,15 +77,16 @@ impl NameDefinition {
85 files.extend(source_root.walk().map(|id| (id.into(), None))); 77 files.extend(source_root.walk().map(|id| (id.into(), None)));
86 } 78 }
87 } 79 }
88
89 return files; 80 return files;
90 } 81 }
91 } 82 }
92 83
84 let mut res = FxHashSet::default();
93 let range = match module_src.ast { 85 let range = match module_src.ast {
94 ModuleSource::Module(m) => Some(m.syntax().text_range()), 86 ModuleSource::Module(m) => Some(m.syntax().text_range()),
95 ModuleSource::SourceFile(_) => None, 87 ModuleSource::SourceFile(_) => None,
96 }; 88 };
97 [(file_id, range)].iter().cloned().collect() 89 res.insert((file_id, range));
90 res
98 } 91 }
99} 92}