aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-03-03 17:50:15 +0000
committerAleksey Kladov <[email protected]>2020-03-03 17:50:15 +0000
commit177229bfde686bbfd66c0f6987f40b5ca282ab45 (patch)
tree60220c642d71ea3dba2c526c7d880c28a14d261a
parent34d6e22fc12209417c15d215052857ddac79cdf4 (diff)
Move reference classification to ra_ide_db
Lost some marks along the way :-(
-rw-r--r--crates/ra_ide/src/goto_definition.rs6
-rw-r--r--crates/ra_ide/src/marks.rs5
-rw-r--r--crates/ra_ide/src/references.rs8
-rw-r--r--crates/ra_ide/src/references/classify.rs84
-rw-r--r--crates/ra_ide_db/src/defs.rs78
5 files changed, 77 insertions, 104 deletions
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index 76ee232a3..6f0dbe065 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -206,7 +206,6 @@ mod tests {
206 206
207 #[test] 207 #[test]
208 fn goto_def_for_macros() { 208 fn goto_def_for_macros() {
209 covers!(goto_def_for_macros);
210 check_goto( 209 check_goto(
211 " 210 "
212 //- /lib.rs 211 //- /lib.rs
@@ -223,7 +222,6 @@ mod tests {
223 222
224 #[test] 223 #[test]
225 fn goto_def_for_macros_from_other_crates() { 224 fn goto_def_for_macros_from_other_crates() {
226 covers!(goto_def_for_macros);
227 check_goto( 225 check_goto(
228 " 226 "
229 //- /lib.rs 227 //- /lib.rs
@@ -335,7 +333,6 @@ mod tests {
335 333
336 #[test] 334 #[test]
337 fn goto_def_for_methods() { 335 fn goto_def_for_methods() {
338 covers!(goto_def_for_methods);
339 check_goto( 336 check_goto(
340 " 337 "
341 //- /lib.rs 338 //- /lib.rs
@@ -355,7 +352,6 @@ mod tests {
355 352
356 #[test] 353 #[test]
357 fn goto_def_for_fields() { 354 fn goto_def_for_fields() {
358 covers!(goto_def_for_fields);
359 check_goto( 355 check_goto(
360 " 356 "
361 //- /lib.rs 357 //- /lib.rs
@@ -374,7 +370,6 @@ mod tests {
374 370
375 #[test] 371 #[test]
376 fn goto_def_for_record_fields() { 372 fn goto_def_for_record_fields() {
377 covers!(goto_def_for_record_fields);
378 check_goto( 373 check_goto(
379 " 374 "
380 //- /lib.rs 375 //- /lib.rs
@@ -787,7 +782,6 @@ mod tests {
787 782
788 #[test] 783 #[test]
789 fn goto_def_for_field_init_shorthand() { 784 fn goto_def_for_field_init_shorthand() {
790 covers!(goto_def_for_field_init_shorthand);
791 check_goto( 785 check_goto(
792 " 786 "
793 //- /lib.rs 787 //- /lib.rs
diff --git a/crates/ra_ide/src/marks.rs b/crates/ra_ide/src/marks.rs
index 7b8b727b4..1236cb773 100644
--- a/crates/ra_ide/src/marks.rs
+++ b/crates/ra_ide/src/marks.rs
@@ -3,11 +3,6 @@
3test_utils::marks!( 3test_utils::marks!(
4 inserts_angle_brackets_for_generics 4 inserts_angle_brackets_for_generics
5 inserts_parens_for_function_calls 5 inserts_parens_for_function_calls
6 goto_def_for_macros
7 goto_def_for_methods
8 goto_def_for_fields
9 goto_def_for_record_fields
10 goto_def_for_field_init_shorthand
11 call_info_bad_offset 6 call_info_bad_offset
12 dont_complete_current_use 7 dont_complete_current_use
13 test_resolve_parent_module_on_module_decl 8 test_resolve_parent_module_on_module_decl
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index 95a5c1914..bfc0c6047 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -9,7 +9,6 @@
9//! at the index that the match starts at and its tree parent is 9//! at the index that the match starts at and its tree parent is
10//! resolved to the search element definition, we get a reference. 10//! resolved to the search element definition, we get a reference.
11 11
12mod classify;
13mod rename; 12mod rename;
14mod search_scope; 13mod search_scope;
15 14
@@ -27,11 +26,8 @@ use test_utils::tested_by;
27 26
28use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; 27use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
29 28
30pub(crate) use self::{ 29pub(crate) use self::rename::rename;
31 classify::{classify_name_ref, NameRefClass}, 30pub(crate) use ra_ide_db::defs::{classify_name, classify_name_ref, Definition, NameRefClass};
32 rename::rename,
33};
34pub(crate) use ra_ide_db::defs::{classify_name, Definition};
35 31
36pub use self::search_scope::SearchScope; 32pub use self::search_scope::SearchScope;
37 33
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs
deleted file mode 100644
index 0bbf893f8..000000000
--- a/crates/ra_ide/src/references/classify.rs
+++ /dev/null
@@ -1,84 +0,0 @@
1//! Functions that are used to classify an element from its definition or reference.
2
3use hir::{Local, PathResolution, Semantics};
4use ra_ide_db::defs::Definition;
5use ra_ide_db::RootDatabase;
6use ra_prof::profile;
7use ra_syntax::{ast, AstNode};
8use test_utils::tested_by;
9
10pub enum NameRefClass {
11 Definition(Definition),
12 FieldShorthand { local: Local, field: Definition },
13}
14
15impl NameRefClass {
16 pub fn definition(self) -> Definition {
17 match self {
18 NameRefClass::Definition(def) => def,
19 NameRefClass::FieldShorthand { local, field: _ } => Definition::Local(local),
20 }
21 }
22}
23
24pub(crate) fn classify_name_ref(
25 sema: &Semantics<RootDatabase>,
26 name_ref: &ast::NameRef,
27) -> Option<NameRefClass> {
28 let _p = profile("classify_name_ref");
29
30 let parent = name_ref.syntax().parent()?;
31
32 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
33 tested_by!(goto_def_for_methods);
34 if let Some(func) = sema.resolve_method_call(&method_call) {
35 return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
36 }
37 }
38
39 if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
40 tested_by!(goto_def_for_fields);
41 if let Some(field) = sema.resolve_field(&field_expr) {
42 return Some(NameRefClass::Definition(Definition::StructField(field)));
43 }
44 }
45
46 if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
47 tested_by!(goto_def_for_record_fields);
48 tested_by!(goto_def_for_field_init_shorthand);
49 if let Some((field, local)) = sema.resolve_record_field(&record_field) {
50 let field = Definition::StructField(field);
51 let res = match local {
52 None => NameRefClass::Definition(field),
53 Some(local) => NameRefClass::FieldShorthand { field, local },
54 };
55 return Some(res);
56 }
57 }
58
59 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
60 tested_by!(goto_def_for_macros);
61 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
62 return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
63 }
64 }
65
66 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
67 let resolved = sema.resolve_path(&path)?;
68 let res = match resolved {
69 PathResolution::Def(def) => Definition::ModuleDef(def),
70 PathResolution::AssocItem(item) => {
71 let def = match item {
72 hir::AssocItem::Function(it) => it.into(),
73 hir::AssocItem::Const(it) => it.into(),
74 hir::AssocItem::TypeAlias(it) => it.into(),
75 };
76 Definition::ModuleDef(def)
77 }
78 PathResolution::Local(local) => Definition::Local(local),
79 PathResolution::TypeParam(par) => Definition::TypeParam(par),
80 PathResolution::Macro(def) => Definition::Macro(def),
81 PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
82 };
83 Some(NameRefClass::Definition(res))
84}
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 215daa441..f057435bf 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -6,8 +6,8 @@
6// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). 6// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
7 7
8use hir::{ 8use hir::{
9 Adt, FieldSource, HasSource, ImplDef, Local, MacroDef, Module, ModuleDef, Name, Semantics, 9 Adt, FieldSource, HasSource, ImplDef, Local, MacroDef, Module, ModuleDef, Name, PathResolution,
10 StructField, TypeParam, 10 Semantics, StructField, TypeParam,
11}; 11};
12use ra_prof::profile; 12use ra_prof::profile;
13use ra_syntax::{ 13use ra_syntax::{
@@ -117,6 +117,8 @@ impl NameClass {
117} 117}
118 118
119pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { 119pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
120 let _p = profile("classify_name");
121
120 if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) { 122 if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) {
121 if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { 123 if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
122 return Some(NameClass::ConstReference(Definition::ModuleDef(def))); 124 return Some(NameClass::ConstReference(Definition::ModuleDef(def)));
@@ -127,7 +129,6 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
127} 129}
128 130
129fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> { 131fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> {
130 let _p = profile("classify_name");
131 let parent = name.syntax().parent()?; 132 let parent = name.syntax().parent()?;
132 133
133 match_ast! { 134 match_ast! {
@@ -192,3 +193,74 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
192 } 193 }
193 } 194 }
194} 195}
196
197pub enum NameRefClass {
198 Definition(Definition),
199 FieldShorthand { local: Local, field: Definition },
200}
201
202impl NameRefClass {
203 pub fn definition(self) -> Definition {
204 match self {
205 NameRefClass::Definition(def) => def,
206 NameRefClass::FieldShorthand { local, field: _ } => Definition::Local(local),
207 }
208 }
209}
210
211pub fn classify_name_ref(
212 sema: &Semantics<RootDatabase>,
213 name_ref: &ast::NameRef,
214) -> Option<NameRefClass> {
215 let _p = profile("classify_name_ref");
216
217 let parent = name_ref.syntax().parent()?;
218
219 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
220 if let Some(func) = sema.resolve_method_call(&method_call) {
221 return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
222 }
223 }
224
225 if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
226 if let Some(field) = sema.resolve_field(&field_expr) {
227 return Some(NameRefClass::Definition(Definition::StructField(field)));
228 }
229 }
230
231 if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
232 if let Some((field, local)) = sema.resolve_record_field(&record_field) {
233 let field = Definition::StructField(field);
234 let res = match local {
235 None => NameRefClass::Definition(field),
236 Some(local) => NameRefClass::FieldShorthand { field, local },
237 };
238 return Some(res);
239 }
240 }
241
242 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
243 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
244 return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
245 }
246 }
247
248 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
249 let resolved = sema.resolve_path(&path)?;
250 let res = match resolved {
251 PathResolution::Def(def) => Definition::ModuleDef(def),
252 PathResolution::AssocItem(item) => {
253 let def = match item {
254 hir::AssocItem::Function(it) => it.into(),
255 hir::AssocItem::Const(it) => it.into(),
256 hir::AssocItem::TypeAlias(it) => it.into(),
257 };
258 Definition::ModuleDef(def)
259 }
260 PathResolution::Local(local) => Definition::Local(local),
261 PathResolution::TypeParam(par) => Definition::TypeParam(par),
262 PathResolution::Macro(def) => Definition::Macro(def),
263 PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
264 };
265 Some(NameRefClass::Definition(res))
266}