diff options
Diffstat (limited to 'crates/ra_ide_api/src/references/search_scope.rs')
-rw-r--r-- | crates/ra_ide_api/src/references/search_scope.rs | 81 |
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. | |
3 | use 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 | ||
5 | use hir::{DefWithBody, HasSource, ModuleSource}; | 6 | use hir::{DefWithBody, HasSource, ModuleSource}; |
6 | use ra_db::{FileId, SourceDatabase, SourceDatabaseExt}; | 7 | use ra_db::{FileId, SourceDatabase, SourceDatabaseExt}; |
7 | use ra_syntax::{AstNode, TextRange}; | 8 | use ra_syntax::{AstNode, TextRange}; |
9 | use rustc_hash::FxHashSet; | ||
8 | 10 | ||
9 | use crate::db::RootDatabase; | 11 | use crate::db::RootDatabase; |
10 | 12 | ||
11 | use super::{NameDefinition, NameKind}; | 13 | use super::{NameDefinition, NameKind}; |
12 | 14 | ||
13 | impl NameDefinition { | 15 | impl 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 | } |