diff options
author | Aleksey Kladov <[email protected]> | 2020-03-03 17:50:15 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-03-03 17:50:15 +0000 |
commit | 177229bfde686bbfd66c0f6987f40b5ca282ab45 (patch) | |
tree | 60220c642d71ea3dba2c526c7d880c28a14d261a | |
parent | 34d6e22fc12209417c15d215052857ddac79cdf4 (diff) |
Move reference classification to ra_ide_db
Lost some marks along the way :-(
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide/src/marks.rs | 5 | ||||
-rw-r--r-- | crates/ra_ide/src/references.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide/src/references/classify.rs | 84 | ||||
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 78 |
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 @@ | |||
3 | test_utils::marks!( | 3 | test_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 | ||
12 | mod classify; | ||
13 | mod rename; | 12 | mod rename; |
14 | mod search_scope; | 13 | mod search_scope; |
15 | 14 | ||
@@ -27,11 +26,8 @@ use test_utils::tested_by; | |||
27 | 26 | ||
28 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; | 27 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; |
29 | 28 | ||
30 | pub(crate) use self::{ | 29 | pub(crate) use self::rename::rename; |
31 | classify::{classify_name_ref, NameRefClass}, | 30 | pub(crate) use ra_ide_db::defs::{classify_name, classify_name_ref, Definition, NameRefClass}; |
32 | rename::rename, | ||
33 | }; | ||
34 | pub(crate) use ra_ide_db::defs::{classify_name, Definition}; | ||
35 | 31 | ||
36 | pub use self::search_scope::SearchScope; | 32 | pub 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 | |||
3 | use hir::{Local, PathResolution, Semantics}; | ||
4 | use ra_ide_db::defs::Definition; | ||
5 | use ra_ide_db::RootDatabase; | ||
6 | use ra_prof::profile; | ||
7 | use ra_syntax::{ast, AstNode}; | ||
8 | use test_utils::tested_by; | ||
9 | |||
10 | pub enum NameRefClass { | ||
11 | Definition(Definition), | ||
12 | FieldShorthand { local: Local, field: Definition }, | ||
13 | } | ||
14 | |||
15 | impl 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 | |||
24 | pub(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(¯o_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 | ||
8 | use hir::{ | 8 | use 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 | }; |
12 | use ra_prof::profile; | 12 | use ra_prof::profile; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ |
@@ -117,6 +117,8 @@ impl NameClass { | |||
117 | } | 117 | } |
118 | 118 | ||
119 | pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { | 119 | pub 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 | ||
129 | fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> { | 131 | fn 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 | |||
197 | pub enum NameRefClass { | ||
198 | Definition(Definition), | ||
199 | FieldShorthand { local: Local, field: Definition }, | ||
200 | } | ||
201 | |||
202 | impl 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 | |||
211 | pub 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(¯o_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 | } | ||