diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-10-23 09:20:18 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-10-23 09:20:18 +0100 |
commit | 4f4fe14fab96c8b40763f9ed5bef51942fd7e504 (patch) | |
tree | cdf5a5b39600b41a9eee301b9760cde1282aeb33 /crates/ra_ide_api/src/references/search_scope.rs | |
parent | c15ee97fff4324981d03f65210d794664c28f0e4 (diff) | |
parent | decfd28bd14b56befa17257694caacc57a090939 (diff) |
Merge #1892
1892: Find usages r=matklad a=viorina
Fixes #1622.
Co-authored-by: Ekaterina Babshukova <[email protected]>
Diffstat (limited to 'crates/ra_ide_api/src/references/search_scope.rs')
-rw-r--r-- | crates/ra_ide_api/src/references/search_scope.rs | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide_api/src/references/search_scope.rs new file mode 100644 index 000000000..5cb69b8fc --- /dev/null +++ b/crates/ra_ide_api/src/references/search_scope.rs | |||
@@ -0,0 +1,92 @@ | |||
1 | //! Generally, `search_scope` returns files that might contain references for the element. | ||
2 | //! For `pub(crate)` things it's a crate, for `pub` things it's a crate and dependant crates. | ||
3 | //! In some cases, the location of the references is known to within a `TextRange`, | ||
4 | //! e.g. for things like local variables. | ||
5 | |||
6 | use hir::{DefWithBody, HasSource, ModuleSource}; | ||
7 | use ra_db::{FileId, SourceDatabase, SourceDatabaseExt}; | ||
8 | use ra_syntax::{AstNode, TextRange}; | ||
9 | use rustc_hash::FxHashSet; | ||
10 | |||
11 | use crate::db::RootDatabase; | ||
12 | |||
13 | use super::{NameDefinition, NameKind}; | ||
14 | |||
15 | impl NameDefinition { | ||
16 | pub(crate) fn search_scope(&self, db: &RootDatabase) -> FxHashSet<(FileId, Option<TextRange>)> { | ||
17 | let module_src = self.container.definition_source(db); | ||
18 | let file_id = module_src.file_id.original_file(db); | ||
19 | |||
20 | if let NameKind::Pat((def, _)) = self.kind { | ||
21 | let mut res = FxHashSet::default(); | ||
22 | let range = match def { | ||
23 | DefWithBody::Function(f) => f.source(db).ast.syntax().text_range(), | ||
24 | DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(), | ||
25 | DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(), | ||
26 | }; | ||
27 | res.insert((file_id, Some(range))); | ||
28 | return res; | ||
29 | } | ||
30 | |||
31 | let vis = | ||
32 | self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or("".to_string()); | ||
33 | |||
34 | if vis.as_str() == "pub(super)" { | ||
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); | ||
39 | |||
40 | match parent_src.ast { | ||
41 | ModuleSource::Module(m) => { | ||
42 | let range = Some(m.syntax().text_range()); | ||
43 | files.insert((file_id, range)); | ||
44 | } | ||
45 | ModuleSource::SourceFile(_) => { | ||
46 | files.insert((file_id, None)); | ||
47 | files.extend(parent_module.children(db).map(|m| { | ||
48 | let src = m.definition_source(db); | ||
49 | (src.file_id.original_file(db), None) | ||
50 | })); | ||
51 | } | ||
52 | } | ||
53 | return files; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | if vis.as_str() != "" { | ||
58 | let source_root_id = db.file_source_root(file_id); | ||
59 | let source_root = db.source_root(source_root_id); | ||
60 | let mut files = | ||
61 | source_root.walk().map(|id| (id.into(), None)).collect::<FxHashSet<_>>(); | ||
62 | |||
63 | // FIXME: add "pub(in path)" | ||
64 | |||
65 | if vis.as_str() == "pub(crate)" { | ||
66 | return files; | ||
67 | } | ||
68 | if vis.as_str() == "pub" { | ||
69 | let krate = self.container.krate(db).unwrap(); | ||
70 | let crate_graph = db.crate_graph(); | ||
71 | for crate_id in crate_graph.iter() { | ||
72 | let mut crate_deps = crate_graph.dependencies(crate_id); | ||
73 | if crate_deps.any(|dep| dep.crate_id() == krate.crate_id()) { | ||
74 | let root_file = crate_graph.crate_root(crate_id); | ||
75 | let source_root_id = db.file_source_root(root_file); | ||
76 | let source_root = db.source_root(source_root_id); | ||
77 | files.extend(source_root.walk().map(|id| (id.into(), None))); | ||
78 | } | ||
79 | } | ||
80 | return files; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | let mut res = FxHashSet::default(); | ||
85 | let range = match module_src.ast { | ||
86 | ModuleSource::Module(m) => Some(m.syntax().text_range()), | ||
87 | ModuleSource::SourceFile(_) => None, | ||
88 | }; | ||
89 | res.insert((file_id, range)); | ||
90 | res | ||
91 | } | ||
92 | } | ||