aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/name_ref_kind.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/name_ref_kind.rs')
-rw-r--r--crates/ra_ide_api/src/name_ref_kind.rs98
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
3use hir::Either;
4use ra_syntax::{ast, AstNode, AstPtr};
5use test_utils::tested_by;
6
7use crate::db::RootDatabase;
8
9pub 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
21pub(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, &macro_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}