aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/search_scope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/search_scope.rs')
-rw-r--r--crates/ra_ide_api/src/search_scope.rs186
1 files changed, 186 insertions, 0 deletions
diff --git a/crates/ra_ide_api/src/search_scope.rs b/crates/ra_ide_api/src/search_scope.rs
new file mode 100644
index 000000000..ca1ac2b03
--- /dev/null
+++ b/crates/ra_ide_api/src/search_scope.rs
@@ -0,0 +1,186 @@
1pub enum SearchScope {
2 Function(hir::Function),
3 Module(hir::Module),
4 Crate(hir::Crate),
5 Crates(Vec<hir::Crate>),
6}
7
8pub struct SearchScope{
9 pub scope: Vec<SyntaxNode>
10}
11
12pub fn find_all_refs(db: &RootDatabase, decl: NameKind) -> Vec<ReferenceDescriptor> {
13 let (module, visibility) = match decl {
14 FieldAccess(field) => {
15 let parent = field.parent_def(db);
16 let module = parent.module(db);
17 let visibility = match parent {
18 VariantDef::Struct(s) => s.source(db).ast.visibility(),
19 VariantDef::EnumVariant(v) => v.parent_enum(db).source(db).ast.visibility(),
20 };
21 (module, visibility)
22 }
23 AssocItem(item) => {
24 let parent = item.parent_trait(db)?;
25 let module = parent.module(db);
26 let visibility = parent.source(db).ast.visibility();
27 (module, visibility)
28 }
29 Def(def) => {
30 let (module, visibility) = match def {
31 ModuleDef::Module(m) => (m, ),
32 ModuleDef::Function(f) => (f.module(db), f.source(db).ast.visibility()),
33 ModuleDef::Adt::Struct(s) => (s.module(db), s.source(db).ast.visibility()),
34 ModuleDef::Adt::Union(u) => (u.module(db), u.source(db).ast.visibility()),
35 ModuleDef::Adt::Enum(e) => (e.module(db), e.source(db).ast.visibility()),
36 ModuleDef::EnumVariant(v) => (v.module(db), v.source(db).ast.visibility()),
37 ModuleDef::Const(c) => (c.module(db), c.source(db).ast.visibility()),
38 ModuleDef::Static(s) => (s.module(db), s.source(db).ast.visibility()),
39 ModuleDef::Trait(t) => (t.module(db), t.source(db).ast.visibility()),
40 ModuleDef::TypeAlias(a) => (a.module(db), a.source(db).ast.visibility()),
41 ModuleDef::BuiltinType(_) => return vec![];
42 };
43 (module, visibility)
44 }
45 // FIXME: add missing kinds
46 _ => return vec![];
47 };
48 let scope = scope(db, module, visibility);
49}
50
51fn scope(db: &RootDatabase, module: hir::Module, item_vis: Option<ast::Visibility>) -> SearchScope {
52 if let Some(v) = item_vis {
53 let krate = module.krate(db)?;
54
55 if v.syntax().text() == "pub" {
56 SearchScope::Crate(krate)
57 }
58 if v.syntax().text() == "pub(crate)" {
59 let crate_graph = db.crate_graph();
60 let crates = crate_graph.iter().filter(|id| {
61 crate_graph.dependencies(id).any(|d| d.crate_id() == krate.crate_id())
62 }).map(|id| Crate { id }).collect::<Vec<_>>();
63 crates.insert(0, krate);
64 SearchScope::Crates(crates)
65 }
66 // FIXME: "pub(super)", "pub(in path)"
67 SearchScope::Module(module)
68 }
69 SearchScope::Module(module)
70}
71
72fn process_one(db, scope: SearchScope, pat) {
73 match scope {
74 SearchScope::Crate(krate) => {
75 let text = db.file_text(position.file_id).as_str();
76 let parse = SourceFile::parse(text);
77 for (offset, name) in text.match_indices(pat) {
78 if let Some() = find_node_at_offset<ast::NameRef>(parse, offset) {
79
80 }
81 }
82 }
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use crate::{
89 mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId,
90 ReferenceSearchResult,
91 };
92 use insta::assert_debug_snapshot;
93 use test_utils::assert_eq_text;
94
95 #[test]
96 fn test_find_all_refs_for_local() {
97 let code = r#"
98 fn main() {
99 let mut i = 1;
100 let j = 1;
101 i = i<|> + j;
102
103 {
104 i = 0;
105 }
106
107 i = 5;
108 }
109 "#;
110
111 let refs = get_all_refs(code);
112 assert_eq!(refs.len(), 5);
113 }
114
115 #[test]
116 fn test_find_all_refs_for_param_inside() {
117 let code = r#"
118 fn foo(i : u32) -> u32 {
119 i<|>
120 }"#;
121
122 let refs = get_all_refs(code);
123 assert_eq!(refs.len(), 2);
124 }
125
126 #[test]
127 fn test_find_all_refs_for_fn_param() {
128 let code = r#"
129 fn foo(i<|> : u32) -> u32 {
130 i
131 }"#;
132
133 let refs = get_all_refs(code);
134 assert_eq!(refs.len(), 2);
135 }
136
137 #[test]
138 fn test_find_all_refs_field_name() {
139 let code = r#"
140 //- /lib.rs
141 struct Foo {
142 spam<|>: u32,
143 }
144 "#;
145
146 let refs = get_all_refs(code);
147 assert_eq!(refs.len(), 1);
148 }
149
150 #[test]
151 fn test_find_all_refs_methods() {
152 let code = r#"
153 //- /lib.rs
154 struct Foo;
155 impl Foo {
156 pub fn a() {
157 self.b()
158 }
159 fn b(&self) {}
160 }
161 "#;
162
163 let refs = get_all_refs(code);
164 assert_eq!(refs.len(), 1);
165 }
166
167 #[test]
168 fn test_find_all_refs_pub_enum() {
169 let code = r#"
170 //- /lib.rs
171 pub enum Foo {
172 A,
173 B<|>,
174 C,
175 }
176 "#;
177
178 let refs = get_all_refs(code);
179 assert_eq!(refs.len(), 1);
180 }
181
182 fn get_all_refs(text: &str) -> ReferenceSearchResult {
183 let (analysis, position) = single_file_with_position(text);
184 analysis.find_all_refs(position).unwrap().unwrap()
185 }
186} \ No newline at end of file