aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/name_kind.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/name_kind.rs')
-rw-r--r--crates/ra_ide_api/src/name_kind.rs83
1 files changed, 43 insertions, 40 deletions
diff --git a/crates/ra_ide_api/src/name_kind.rs b/crates/ra_ide_api/src/name_kind.rs
index 6d1eb153f..8eef540f6 100644
--- a/crates/ra_ide_api/src/name_kind.rs
+++ b/crates/ra_ide_api/src/name_kind.rs
@@ -10,6 +10,7 @@ use ra_syntax::{ast, ast::VisibilityOwner, AstNode, AstPtr};
10 10
11use crate::db::RootDatabase; 11use crate::db::RootDatabase;
12 12
13#[derive(PartialEq, Eq)]
13pub enum NameKind { 14pub enum NameKind {
14 Macro(MacroDef), 15 Macro(MacroDef),
15 FieldAccess(StructField), 16 FieldAccess(StructField),
@@ -21,23 +22,24 @@ pub enum NameKind {
21 GenericParam(u32), 22 GenericParam(u32),
22} 23}
23 24
24pub(crate) struct Declaration { 25#[derive(PartialEq, Eq)]
26pub(crate) struct Definition {
25 pub visibility: Option<ast::Visibility>, 27 pub visibility: Option<ast::Visibility>,
26 pub container: Module, 28 pub container: Module,
27 pub item: NameKind, 29 pub item: NameKind,
28} 30}
29 31
30trait HasDeclaration { 32trait HasDefinition {
31 type Def; 33 type Def;
32 type Ref; 34 type Ref;
33 35
34 fn declaration(self, db: &RootDatabase) -> Declaration; 36 fn definition(self, db: &RootDatabase) -> Definition;
35 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Declaration>; 37 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition>;
36 fn from_ref( 38 fn from_ref(
37 db: &RootDatabase, 39 db: &RootDatabase,
38 analyzer: &SourceAnalyzer, 40 analyzer: &SourceAnalyzer,
39 refer: Self::Ref, 41 refer: Self::Ref,
40 ) -> Option<Declaration>; 42 ) -> Option<Definition>;
41} 43}
42 44
43macro_rules! match_ast { 45macro_rules! match_ast {
@@ -55,7 +57,7 @@ pub(crate) fn classify_name_ref(
55 file_id: FileId, 57 file_id: FileId,
56 analyzer: &SourceAnalyzer, 58 analyzer: &SourceAnalyzer,
57 name_ref: &ast::NameRef, 59 name_ref: &ast::NameRef,
58) -> Option<Declaration> { 60) -> Option<Definition> {
59 let parent = name_ref.syntax().parent()?; 61 let parent = name_ref.syntax().parent()?;
60 match_ast! { 62 match_ast! {
61 match parent { 63 match parent {
@@ -64,7 +66,7 @@ pub(crate) fn classify_name_ref(
64 }, 66 },
65 ast::FieldExpr(it) => { 67 ast::FieldExpr(it) => {
66 if let Some(field) = analyzer.resolve_field(&it) { 68 if let Some(field) = analyzer.resolve_field(&it) {
67 return Some(field.declaration(db)); 69 return Some(field.definition(db));
68 } 70 }
69 }, 71 },
70 ast::RecordField(it) => { 72 ast::RecordField(it) => {
@@ -73,7 +75,7 @@ pub(crate) fn classify_name_ref(
73 let hir_path = Path::from_name_ref(name_ref); 75 let hir_path = Path::from_name_ref(name_ref);
74 let hir_name = hir_path.as_ident()?; 76 let hir_name = hir_path.as_ident()?;
75 let field = variant_def.field(db, hir_name)?; 77 let field = variant_def.field(db, hir_name)?;
76 return Some(field.declaration(db)); 78 return Some(field.definition(db));
77 } 79 }
78 }, 80 },
79 _ => (), 81 _ => (),
@@ -83,12 +85,13 @@ pub(crate) fn classify_name_ref(
83 let ast = ModuleSource::from_child_node(db, file_id, &parent); 85 let ast = ModuleSource::from_child_node(db, file_id, &parent);
84 let file_id = file_id.into(); 86 let file_id = file_id.into();
85 let container = Module::from_definition(db, Source { file_id, ast })?; 87 let container = Module::from_definition(db, Source { file_id, ast })?;
88 let visibility = None;
86 89
87 if let Some(macro_call) = 90 if let Some(macro_call) =
88 parent.parent().and_then(|node| node.parent()).and_then(ast::MacroCall::cast) 91 parent.parent().and_then(|node| node.parent()).and_then(ast::MacroCall::cast)
89 { 92 {
90 if let Some(mac) = analyzer.resolve_macro_call(db, &macro_call) { 93 if let Some(mac) = analyzer.resolve_macro_call(db, &macro_call) {
91 return Some(Declaration { item: NameKind::Macro(mac), container, visibility: None }); 94 return Some(Definition { item: NameKind::Macro(mac), container, visibility });
92 } 95 }
93 } 96 }
94 97
@@ -96,24 +99,24 @@ pub(crate) fn classify_name_ref(
96 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?; 99 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
97 let resolved = analyzer.resolve_path(db, &path)?; 100 let resolved = analyzer.resolve_path(db, &path)?;
98 match resolved { 101 match resolved {
99 PathResolution::Def(def) => Some(def.declaration(db)), 102 PathResolution::Def(def) => Some(def.definition(db)),
100 PathResolution::LocalBinding(Either::A(pat)) => decl_from_pat(db, file_id, pat), 103 PathResolution::LocalBinding(Either::A(pat)) => decl_from_pat(db, file_id, pat),
101 PathResolution::LocalBinding(Either::B(par)) => { 104 PathResolution::LocalBinding(Either::B(par)) => {
102 Some(Declaration { item: NameKind::SelfParam(par), container, visibility: None }) 105 Some(Definition { item: NameKind::SelfParam(par), container, visibility })
103 } 106 }
104 PathResolution::GenericParam(par) => { 107 PathResolution::GenericParam(par) => {
105 // FIXME: get generic param def 108 // FIXME: get generic param def
106 Some(Declaration { item: NameKind::GenericParam(par), container, visibility: None }) 109 Some(Definition { item: NameKind::GenericParam(par), container, visibility })
107 } 110 }
108 PathResolution::Macro(def) => { 111 PathResolution::Macro(def) => {
109 Some(Declaration { item: NameKind::Macro(def), container, visibility: None }) 112 Some(Definition { item: NameKind::Macro(def), container, visibility })
110 } 113 }
111 PathResolution::SelfType(impl_block) => { 114 PathResolution::SelfType(impl_block) => {
112 let ty = impl_block.target_ty(db); 115 let ty = impl_block.target_ty(db);
113 let container = impl_block.module(); 116 let container = impl_block.module();
114 Some(Declaration { item: NameKind::SelfType(ty), container, visibility: None }) 117 Some(Definition { item: NameKind::SelfType(ty), container, visibility })
115 } 118 }
116 PathResolution::AssocItem(assoc) => Some(assoc.declaration(db)), 119 PathResolution::AssocItem(assoc) => Some(assoc.definition(db)),
117 } 120 }
118} 121}
119 122
@@ -121,7 +124,7 @@ pub(crate) fn classify_name(
121 db: &RootDatabase, 124 db: &RootDatabase,
122 file_id: FileId, 125 file_id: FileId,
123 name: &ast::Name, 126 name: &ast::Name,
124) -> Option<Declaration> { 127) -> Option<Definition> {
125 let parent = name.syntax().parent()?; 128 let parent = name.syntax().parent()?;
126 let file_id = file_id.into(); 129 let file_id = file_id.into();
127 130
@@ -145,7 +148,7 @@ pub(crate) fn classify_name(
145 ast::EnumVariant(it) => { 148 ast::EnumVariant(it) => {
146 let src = hir::Source { file_id, ast: it.clone() }; 149 let src = hir::Source { file_id, ast: it.clone() };
147 let def: ModuleDef = EnumVariant::from_source(db, src)?.into(); 150 let def: ModuleDef = EnumVariant::from_source(db, src)?.into();
148 Some(def.declaration(db)) 151 Some(def.definition(db))
149 }, 152 },
150 ast::ModuleItem(it) => { 153 ast::ModuleItem(it) => {
151 ModuleDef::from_def(db, file_id, it) 154 ModuleDef::from_def(db, file_id, it)
@@ -159,7 +162,7 @@ fn decl_from_pat(
159 db: &RootDatabase, 162 db: &RootDatabase,
160 file_id: HirFileId, 163 file_id: HirFileId,
161 pat: AstPtr<ast::BindPat>, 164 pat: AstPtr<ast::BindPat>,
162) -> Option<Declaration> { 165) -> Option<Definition> {
163 let root = db.parse_or_expand(file_id)?; 166 let root = db.parse_or_expand(file_id)?;
164 // FIXME: use match_ast! 167 // FIXME: use match_ast!
165 let def = pat.to_node(&root).syntax().ancestors().find_map(|node| { 168 let def = pat.to_node(&root).syntax().ancestors().find_map(|node| {
@@ -178,14 +181,14 @@ fn decl_from_pat(
178 })?; 181 })?;
179 let item = NameKind::Pat((def, pat)); 182 let item = NameKind::Pat((def, pat));
180 let container = def.module(db); 183 let container = def.module(db);
181 Some(Declaration { item, container, visibility: None }) 184 Some(Definition { item, container, visibility: None })
182} 185}
183 186
184impl HasDeclaration for StructField { 187impl HasDefinition for StructField {
185 type Def = ast::RecordFieldDef; 188 type Def = ast::RecordFieldDef;
186 type Ref = ast::FieldExpr; 189 type Ref = ast::FieldExpr;
187 190
188 fn declaration(self, db: &RootDatabase) -> Declaration { 191 fn definition(self, db: &RootDatabase) -> Definition {
189 let item = NameKind::FieldAccess(self); 192 let item = NameKind::FieldAccess(self);
190 let parent = self.parent_def(db); 193 let parent = self.parent_def(db);
191 let container = parent.module(db); 194 let container = parent.module(db);
@@ -193,30 +196,30 @@ impl HasDeclaration for StructField {
193 VariantDef::Struct(s) => s.source(db).ast.visibility(), 196 VariantDef::Struct(s) => s.source(db).ast.visibility(),
194 VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(), 197 VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(),
195 }; 198 };
196 Declaration { item, container, visibility } 199 Definition { item, container, visibility }
197 } 200 }
198 201
199 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Declaration> { 202 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition> {
200 let src = hir::Source { file_id, ast: hir::FieldSource::Named(def) }; 203 let src = hir::Source { file_id, ast: hir::FieldSource::Named(def) };
201 let field = StructField::from_source(db, src)?; 204 let field = StructField::from_source(db, src)?;
202 Some(field.declaration(db)) 205 Some(field.definition(db))
203 } 206 }
204 207
205 fn from_ref( 208 fn from_ref(
206 db: &RootDatabase, 209 db: &RootDatabase,
207 analyzer: &SourceAnalyzer, 210 analyzer: &SourceAnalyzer,
208 refer: Self::Ref, 211 refer: Self::Ref,
209 ) -> Option<Declaration> { 212 ) -> Option<Definition> {
210 let field = analyzer.resolve_field(&refer)?; 213 let field = analyzer.resolve_field(&refer)?;
211 Some(field.declaration(db)) 214 Some(field.definition(db))
212 } 215 }
213} 216}
214 217
215impl HasDeclaration for AssocItem { 218impl HasDefinition for AssocItem {
216 type Def = ast::ImplItem; 219 type Def = ast::ImplItem;
217 type Ref = ast::MethodCallExpr; 220 type Ref = ast::MethodCallExpr;
218 221
219 fn declaration(self, db: &RootDatabase) -> Declaration { 222 fn definition(self, db: &RootDatabase) -> Definition {
220 let item = NameKind::AssocItem(self); 223 let item = NameKind::AssocItem(self);
221 let container = self.module(db); 224 let container = self.module(db);
222 let visibility = match self { 225 let visibility = match self {
@@ -224,30 +227,30 @@ impl HasDeclaration for AssocItem {
224 AssocItem::Const(c) => c.source(db).ast.visibility(), 227 AssocItem::Const(c) => c.source(db).ast.visibility(),
225 AssocItem::TypeAlias(a) => a.source(db).ast.visibility(), 228 AssocItem::TypeAlias(a) => a.source(db).ast.visibility(),
226 }; 229 };
227 Declaration { item, container, visibility } 230 Definition { item, container, visibility }
228 } 231 }
229 232
230 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Declaration> { 233 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition> {
231 let src = hir::Source { file_id, ast: def }; 234 let src = hir::Source { file_id, ast: def };
232 let item = AssocItem::from_source(db, src)?; 235 let item = AssocItem::from_source(db, src)?;
233 Some(item.declaration(db)) 236 Some(item.definition(db))
234 } 237 }
235 238
236 fn from_ref( 239 fn from_ref(
237 db: &RootDatabase, 240 db: &RootDatabase,
238 analyzer: &SourceAnalyzer, 241 analyzer: &SourceAnalyzer,
239 refer: Self::Ref, 242 refer: Self::Ref,
240 ) -> Option<Declaration> { 243 ) -> Option<Definition> {
241 let func: AssocItem = analyzer.resolve_method_call(&refer)?.into(); 244 let func: AssocItem = analyzer.resolve_method_call(&refer)?.into();
242 Some(func.declaration(db)) 245 Some(func.definition(db))
243 } 246 }
244} 247}
245 248
246impl HasDeclaration for ModuleDef { 249impl HasDefinition for ModuleDef {
247 type Def = ast::ModuleItem; 250 type Def = ast::ModuleItem;
248 type Ref = ast::Path; 251 type Ref = ast::Path;
249 252
250 fn declaration(self, db: &RootDatabase) -> Declaration { 253 fn definition(self, db: &RootDatabase) -> Definition {
251 let (container, visibility) = match self { 254 let (container, visibility) = match self {
252 ModuleDef::Module(it) => { 255 ModuleDef::Module(it) => {
253 let container = it.parent(db).or_else(|| Some(it)).unwrap(); 256 let container = it.parent(db).or_else(|| Some(it)).unwrap();
@@ -270,22 +273,22 @@ impl HasDeclaration for ModuleDef {
270 ModuleDef::BuiltinType(..) => unreachable!(), 273 ModuleDef::BuiltinType(..) => unreachable!(),
271 }; 274 };
272 let item = NameKind::Def(self); 275 let item = NameKind::Def(self);
273 Declaration { item, container, visibility } 276 Definition { item, container, visibility }
274 } 277 }
275 278
276 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Declaration> { 279 fn from_def(db: &RootDatabase, file_id: HirFileId, def: Self::Def) -> Option<Definition> {
277 let src = hir::Source { file_id, ast: def }; 280 let src = hir::Source { file_id, ast: def };
278 let def = ModuleDef::from_source(db, src)?; 281 let def = ModuleDef::from_source(db, src)?;
279 Some(def.declaration(db)) 282 Some(def.definition(db))
280 } 283 }
281 284
282 fn from_ref( 285 fn from_ref(
283 db: &RootDatabase, 286 db: &RootDatabase,
284 analyzer: &SourceAnalyzer, 287 analyzer: &SourceAnalyzer,
285 refer: Self::Ref, 288 refer: Self::Ref,
286 ) -> Option<Declaration> { 289 ) -> Option<Definition> {
287 None 290 None
288 } 291 }
289} 292}
290 293
291// FIXME: impl HasDeclaration for hir::MacroDef 294// FIXME: impl HasDefinition for hir::MacroDef