diff options
Diffstat (limited to 'crates/ra_ide_api/src/references/definition.rs')
-rw-r--r-- | crates/ra_ide_api/src/references/definition.rs | 177 |
1 files changed, 0 insertions, 177 deletions
diff --git a/crates/ra_ide_api/src/references/definition.rs b/crates/ra_ide_api/src/references/definition.rs deleted file mode 100644 index 65b1f8dd7..000000000 --- a/crates/ra_ide_api/src/references/definition.rs +++ /dev/null | |||
@@ -1,177 +0,0 @@ | |||
1 | use hir::{ | ||
2 | db::AstDatabase, Adt, AssocItem, DefWithBody, FromSource, HasSource, HirFileId, MacroDef, | ||
3 | Module, ModuleDef, SourceAnalyzer, StructField, Ty, VariantDef, | ||
4 | }; | ||
5 | use ra_syntax::{ast, ast::VisibilityOwner, AstNode, AstPtr}; | ||
6 | |||
7 | use crate::db::RootDatabase; | ||
8 | |||
9 | #[derive(Debug, PartialEq, Eq)] | ||
10 | pub enum NameKind { | ||
11 | Macro(MacroDef), | ||
12 | FieldAccess(StructField), | ||
13 | AssocItem(AssocItem), | ||
14 | Def(ModuleDef), | ||
15 | SelfType(Ty), | ||
16 | Pat((DefWithBody, AstPtr<ast::BindPat>)), | ||
17 | SelfParam(AstPtr<ast::SelfParam>), | ||
18 | GenericParam(u32), | ||
19 | } | ||
20 | |||
21 | #[derive(PartialEq, Eq)] | ||
22 | pub(crate) struct Definition { | ||
23 | pub visibility: Option<ast::Visibility>, | ||
24 | pub container: Module, | ||
25 | pub item: NameKind, | ||
26 | } | ||
27 | |||
28 | pub(super) trait HasDefinition { | ||
29 | type Def; | ||
30 | type Ref; | ||
31 | |||
32 | fn definition(self, db: &RootDatabase) -> Definition; | ||
33 | fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition>; | ||
34 | fn from_ref( | ||
35 | db: &RootDatabase, | ||
36 | analyzer: &SourceAnalyzer, | ||
37 | refer: Self::Ref, | ||
38 | ) -> Option<Definition>; | ||
39 | } | ||
40 | |||
41 | // fn decl_from_pat( | ||
42 | // db: &RootDatabase, | ||
43 | // file_id: HirFileId, | ||
44 | // pat: AstPtr<ast::BindPat>, | ||
45 | // ) -> Option<Definition> { | ||
46 | // let root = db.parse_or_expand(file_id)?; | ||
47 | // // FIXME: use match_ast! | ||
48 | // let def = pat.to_node(&root).syntax().ancestors().find_map(|node| { | ||
49 | // if let Some(it) = ast::FnDef::cast(node.clone()) { | ||
50 | // let src = hir::Source { file_id, ast: it }; | ||
51 | // Some(hir::Function::from_source(db, src)?.into()) | ||
52 | // } else if let Some(it) = ast::ConstDef::cast(node.clone()) { | ||
53 | // let src = hir::Source { file_id, ast: it }; | ||
54 | // Some(hir::Const::from_source(db, src)?.into()) | ||
55 | // } else if let Some(it) = ast::StaticDef::cast(node.clone()) { | ||
56 | // let src = hir::Source { file_id, ast: it }; | ||
57 | // Some(hir::Static::from_source(db, src)?.into()) | ||
58 | // } else { | ||
59 | // None | ||
60 | // } | ||
61 | // })?; | ||
62 | // let item = NameKind::Pat((def, pat)); | ||
63 | // let container = def.module(db); | ||
64 | // Some(Definition { item, container, visibility: None }) | ||
65 | // } | ||
66 | |||
67 | impl HasDefinition for StructField { | ||
68 | type Def = ast::RecordFieldDef; | ||
69 | type Ref = ast::FieldExpr; | ||
70 | |||
71 | fn definition(self, db: &RootDatabase) -> Definition { | ||
72 | let item = NameKind::FieldAccess(self); | ||
73 | let parent = self.parent_def(db); | ||
74 | let container = parent.module(db); | ||
75 | let visibility = match parent { | ||
76 | VariantDef::Struct(s) => s.source(db).ast.visibility(), | ||
77 | VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(), | ||
78 | }; | ||
79 | Definition { item, container, visibility } | ||
80 | } | ||
81 | |||
82 | fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition> { | ||
83 | let src = hir::Source { file_id, ast: hir::FieldSource::Named(def) }; | ||
84 | let field = StructField::from_source(db, src)?; | ||
85 | Some(field.definition(db)) | ||
86 | } | ||
87 | |||
88 | fn from_ref( | ||
89 | db: &RootDatabase, | ||
90 | analyzer: &SourceAnalyzer, | ||
91 | refer: Self::Ref, | ||
92 | ) -> Option<Definition> { | ||
93 | let field = analyzer.resolve_field(&refer)?; | ||
94 | Some(field.definition(db)) | ||
95 | } | ||
96 | } | ||
97 | |||
98 | impl HasDefinition for AssocItem { | ||
99 | type Def = ast::ImplItem; | ||
100 | type Ref = ast::MethodCallExpr; | ||
101 | |||
102 | fn definition(self, db: &RootDatabase) -> Definition { | ||
103 | let item = NameKind::AssocItem(self); | ||
104 | let container = self.module(db); | ||
105 | let visibility = match self { | ||
106 | AssocItem::Function(f) => f.source(db).ast.visibility(), | ||
107 | AssocItem::Const(c) => c.source(db).ast.visibility(), | ||
108 | AssocItem::TypeAlias(a) => a.source(db).ast.visibility(), | ||
109 | }; | ||
110 | Definition { item, container, visibility } | ||
111 | } | ||
112 | |||
113 | fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition> { | ||
114 | if def.syntax().parent().and_then(ast::ItemList::cast).is_none() { | ||
115 | return None; | ||
116 | } | ||
117 | let src = hir::Source { file_id, ast: def }; | ||
118 | let item = AssocItem::from_source(db, src)?; | ||
119 | Some(item.definition(db)) | ||
120 | } | ||
121 | |||
122 | fn from_ref( | ||
123 | db: &RootDatabase, | ||
124 | analyzer: &SourceAnalyzer, | ||
125 | refer: Self::Ref, | ||
126 | ) -> Option<Definition> { | ||
127 | let func: AssocItem = analyzer.resolve_method_call(&refer)?.into(); | ||
128 | Some(func.definition(db)) | ||
129 | } | ||
130 | } | ||
131 | |||
132 | impl HasDefinition for ModuleDef { | ||
133 | type Def = ast::ModuleItem; | ||
134 | type Ref = ast::Path; | ||
135 | |||
136 | fn definition(self, db: &RootDatabase) -> Definition { | ||
137 | let (container, visibility) = match self { | ||
138 | ModuleDef::Module(it) => { | ||
139 | let container = it.parent(db).or_else(|| Some(it)).unwrap(); | ||
140 | let visibility = it.declaration_source(db).and_then(|s| s.ast.visibility()); | ||
141 | (container, visibility) | ||
142 | } | ||
143 | ModuleDef::EnumVariant(it) => { | ||
144 | let container = it.module(db); | ||
145 | let visibility = it.source(db).ast.parent_enum().visibility(); | ||
146 | (container, visibility) | ||
147 | } | ||
148 | ModuleDef::Function(it) => (it.module(db), it.source(db).ast.visibility()), | ||
149 | ModuleDef::Const(it) => (it.module(db), it.source(db).ast.visibility()), | ||
150 | ModuleDef::Static(it) => (it.module(db), it.source(db).ast.visibility()), | ||
151 | ModuleDef::Trait(it) => (it.module(db), it.source(db).ast.visibility()), | ||
152 | ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).ast.visibility()), | ||
153 | ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).ast.visibility()), | ||
154 | ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).ast.visibility()), | ||
155 | ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).ast.visibility()), | ||
156 | ModuleDef::BuiltinType(..) => unreachable!(), | ||
157 | }; | ||
158 | let item = NameKind::Def(self); | ||
159 | Definition { item, container, visibility } | ||
160 | } | ||
161 | |||
162 | fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition> { | ||
163 | let src = hir::Source { file_id, ast: def }; | ||
164 | let def = ModuleDef::from_source(db, src)?; | ||
165 | Some(def.definition(db)) | ||
166 | } | ||
167 | |||
168 | fn from_ref( | ||
169 | db: &RootDatabase, | ||
170 | analyzer: &SourceAnalyzer, | ||
171 | refer: Self::Ref, | ||
172 | ) -> Option<Definition> { | ||
173 | None | ||
174 | } | ||
175 | } | ||
176 | |||
177 | // FIXME: impl HasDefinition for hir::MacroDef | ||