diff options
Diffstat (limited to 'crates/ra_ide_api/src/name_ref_kind.rs')
-rw-r--r-- | crates/ra_ide_api/src/name_ref_kind.rs | 98 |
1 files changed, 0 insertions, 98 deletions
diff --git a/crates/ra_ide_api/src/name_ref_kind.rs b/crates/ra_ide_api/src/name_ref_kind.rs deleted file mode 100644 index 149585971..000000000 --- a/crates/ra_ide_api/src/name_ref_kind.rs +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use hir::Either; | ||
4 | use ra_syntax::{ast, AstNode, AstPtr}; | ||
5 | use test_utils::tested_by; | ||
6 | |||
7 | use crate::db::RootDatabase; | ||
8 | |||
9 | pub enum NameRefKind { | ||
10 | Method(hir::Function), | ||
11 | Macro(hir::MacroDef), | ||
12 | FieldAccess(hir::StructField), | ||
13 | AssocItem(hir::AssocItem), | ||
14 | Def(hir::ModuleDef), | ||
15 | SelfType(hir::Ty), | ||
16 | Pat(AstPtr<ast::BindPat>), | ||
17 | SelfParam(AstPtr<ast::SelfParam>), | ||
18 | GenericParam(u32), | ||
19 | } | ||
20 | |||
21 | pub(crate) fn classify_name_ref( | ||
22 | db: &RootDatabase, | ||
23 | analyzer: &hir::SourceAnalyzer, | ||
24 | name_ref: &ast::NameRef, | ||
25 | ) -> Option<NameRefKind> { | ||
26 | use NameRefKind::*; | ||
27 | |||
28 | // Check if it is a method | ||
29 | if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) { | ||
30 | tested_by!(goto_definition_works_for_methods); | ||
31 | if let Some(func) = analyzer.resolve_method_call(&method_call) { | ||
32 | return Some(Method(func)); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | // It could be a macro call | ||
37 | if let Some(macro_call) = name_ref | ||
38 | .syntax() | ||
39 | .parent() | ||
40 | .and_then(|node| node.parent()) | ||
41 | .and_then(|node| node.parent()) | ||
42 | .and_then(ast::MacroCall::cast) | ||
43 | { | ||
44 | tested_by!(goto_definition_works_for_macros); | ||
45 | if let Some(mac) = analyzer.resolve_macro_call(db, ¯o_call) { | ||
46 | return Some(Macro(mac)); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | // It could also be a field access | ||
51 | if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::FieldExpr::cast) { | ||
52 | tested_by!(goto_definition_works_for_fields); | ||
53 | if let Some(field) = analyzer.resolve_field(&field_expr) { | ||
54 | return Some(FieldAccess(field)); | ||
55 | }; | ||
56 | } | ||
57 | |||
58 | // It could also be a named field | ||
59 | if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::RecordField::cast) { | ||
60 | tested_by!(goto_definition_works_for_record_fields); | ||
61 | |||
62 | let record_lit = field_expr.syntax().ancestors().find_map(ast::RecordLit::cast); | ||
63 | |||
64 | if let Some(ty) = record_lit.and_then(|lit| analyzer.type_of(db, &lit.into())) { | ||
65 | if let Some((hir::Adt::Struct(s), _)) = ty.as_adt() { | ||
66 | let hir_path = hir::Path::from_name_ref(name_ref); | ||
67 | let hir_name = hir_path.as_ident().unwrap(); | ||
68 | |||
69 | if let Some(field) = s.field(db, hir_name) { | ||
70 | return Some(FieldAccess(field)); | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | |||
76 | // General case, a path or a local: | ||
77 | if let Some(path) = name_ref.syntax().ancestors().find_map(ast::Path::cast) { | ||
78 | if let Some(resolved) = analyzer.resolve_path(db, &path) { | ||
79 | return match resolved { | ||
80 | hir::PathResolution::Def(def) => Some(Def(def)), | ||
81 | hir::PathResolution::LocalBinding(Either::A(pat)) => Some(Pat(pat)), | ||
82 | hir::PathResolution::LocalBinding(Either::B(par)) => Some(SelfParam(par)), | ||
83 | hir::PathResolution::GenericParam(par) => { | ||
84 | // FIXME: get generic param def | ||
85 | Some(GenericParam(par)) | ||
86 | } | ||
87 | hir::PathResolution::Macro(def) => Some(Macro(def)), | ||
88 | hir::PathResolution::SelfType(impl_block) => { | ||
89 | let ty = impl_block.target_ty(db); | ||
90 | Some(SelfType(ty)) | ||
91 | } | ||
92 | hir::PathResolution::AssocItem(assoc) => Some(AssocItem(assoc)), | ||
93 | }; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | None | ||
98 | } | ||