diff options
Diffstat (limited to 'crates/ra_hir_def/src/lib.rs')
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 180 |
1 files changed, 161 insertions, 19 deletions
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index a240a10b8..0af41de87 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -13,10 +13,12 @@ pub mod path; | |||
13 | pub mod type_ref; | 13 | pub mod type_ref; |
14 | pub mod builtin_type; | 14 | pub mod builtin_type; |
15 | pub mod adt; | 15 | pub mod adt; |
16 | pub mod imp; | 16 | pub mod impls; |
17 | pub mod diagnostics; | 17 | pub mod diagnostics; |
18 | pub mod expr; | 18 | pub mod expr; |
19 | pub mod body; | 19 | pub mod body; |
20 | pub mod generics; | ||
21 | pub mod traits; | ||
20 | 22 | ||
21 | #[cfg(test)] | 23 | #[cfg(test)] |
22 | mod test_db; | 24 | mod test_db; |
@@ -80,7 +82,7 @@ impl ModuleSource { | |||
80 | 82 | ||
81 | pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource { | 83 | pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource { |
82 | if let Some(m) = | 84 | if let Some(m) = |
83 | child.ast.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | 85 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) |
84 | { | 86 | { |
85 | ModuleSource::Module(m) | 87 | ModuleSource::Module(m) |
86 | } else { | 88 | } else { |
@@ -184,8 +186,8 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
184 | } | 186 | } |
185 | fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { | 187 | fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { |
186 | let loc = self.lookup_intern(db); | 188 | let loc = self.lookup_intern(db); |
187 | let ast = loc.ast_id.to_node(db); | 189 | let value = loc.ast_id.to_node(db); |
188 | Source { file_id: loc.ast_id.file_id(), ast } | 190 | Source { file_id: loc.ast_id.file_id(), value } |
189 | } | 191 | } |
190 | fn module(self, db: &impl InternDatabase) -> ModuleId { | 192 | fn module(self, db: &impl InternDatabase) -> ModuleId { |
191 | let loc = self.lookup_intern(db); | 193 | let loc = self.lookup_intern(db); |
@@ -197,12 +199,23 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
197 | pub struct FunctionId(salsa::InternId); | 199 | pub struct FunctionId(salsa::InternId); |
198 | impl_intern_key!(FunctionId); | 200 | impl_intern_key!(FunctionId); |
199 | 201 | ||
200 | impl AstItemDef<ast::FnDef> for FunctionId { | 202 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
201 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::FnDef>) -> Self { | 203 | pub struct FunctionLoc { |
202 | db.intern_function(loc) | 204 | pub container: ContainerId, |
205 | pub ast_id: AstId<ast::FnDef>, | ||
206 | } | ||
207 | |||
208 | impl Intern for FunctionLoc { | ||
209 | type ID = FunctionId; | ||
210 | fn intern(self, db: &impl db::DefDatabase2) -> FunctionId { | ||
211 | db.intern_function(self) | ||
203 | } | 212 | } |
204 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::FnDef> { | 213 | } |
205 | db.lookup_intern_function(self) | 214 | |
215 | impl Lookup for FunctionId { | ||
216 | type Data = FunctionLoc; | ||
217 | fn lookup(&self, db: &impl db::DefDatabase2) -> FunctionLoc { | ||
218 | db.lookup_intern_function(*self) | ||
206 | } | 219 | } |
207 | } | 220 | } |
208 | 221 | ||
@@ -276,12 +289,23 @@ impl_arena_id!(LocalStructFieldId); | |||
276 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 289 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
277 | pub struct ConstId(salsa::InternId); | 290 | pub struct ConstId(salsa::InternId); |
278 | impl_intern_key!(ConstId); | 291 | impl_intern_key!(ConstId); |
279 | impl AstItemDef<ast::ConstDef> for ConstId { | 292 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
280 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self { | 293 | pub struct ConstLoc { |
281 | db.intern_const(loc) | 294 | pub container: ContainerId, |
295 | pub ast_id: AstId<ast::ConstDef>, | ||
296 | } | ||
297 | |||
298 | impl Intern for ConstLoc { | ||
299 | type ID = ConstId; | ||
300 | fn intern(self, db: &impl db::DefDatabase2) -> ConstId { | ||
301 | db.intern_const(self) | ||
282 | } | 302 | } |
283 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ConstDef> { | 303 | } |
284 | db.lookup_intern_const(self) | 304 | |
305 | impl Lookup for ConstId { | ||
306 | type Data = ConstLoc; | ||
307 | fn lookup(&self, db: &impl db::DefDatabase2) -> ConstLoc { | ||
308 | db.lookup_intern_const(*self) | ||
285 | } | 309 | } |
286 | } | 310 | } |
287 | 311 | ||
@@ -312,12 +336,24 @@ impl AstItemDef<ast::TraitDef> for TraitId { | |||
312 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 336 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
313 | pub struct TypeAliasId(salsa::InternId); | 337 | pub struct TypeAliasId(salsa::InternId); |
314 | impl_intern_key!(TypeAliasId); | 338 | impl_intern_key!(TypeAliasId); |
315 | impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { | 339 | |
316 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self { | 340 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
317 | db.intern_type_alias(loc) | 341 | pub struct TypeAliasLoc { |
342 | pub container: ContainerId, | ||
343 | pub ast_id: AstId<ast::TypeAliasDef>, | ||
344 | } | ||
345 | |||
346 | impl Intern for TypeAliasLoc { | ||
347 | type ID = TypeAliasId; | ||
348 | fn intern(self, db: &impl db::DefDatabase2) -> TypeAliasId { | ||
349 | db.intern_type_alias(self) | ||
318 | } | 350 | } |
319 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TypeAliasDef> { | 351 | } |
320 | db.lookup_intern_type_alias(self) | 352 | |
353 | impl Lookup for TypeAliasId { | ||
354 | type Data = TypeAliasLoc; | ||
355 | fn lookup(&self, db: &impl db::DefDatabase2) -> TypeAliasLoc { | ||
356 | db.lookup_intern_type_alias(*self) | ||
321 | } | 357 | } |
322 | } | 358 | } |
323 | 359 | ||
@@ -352,6 +388,13 @@ macro_rules! impl_froms { | |||
352 | } | 388 | } |
353 | } | 389 | } |
354 | 390 | ||
391 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
392 | pub enum ContainerId { | ||
393 | ModuleId(ModuleId), | ||
394 | ImplId(ImplId), | ||
395 | TraitId(TraitId), | ||
396 | } | ||
397 | |||
355 | /// A Data Type | 398 | /// A Data Type |
356 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 399 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
357 | pub enum AdtId { | 400 | pub enum AdtId { |
@@ -408,3 +451,102 @@ pub enum AssocItemId { | |||
408 | // require not implementing From, and instead having some checked way of | 451 | // require not implementing From, and instead having some checked way of |
409 | // casting them, and somehow making the constructors private, which would be annoying. | 452 | // casting them, and somehow making the constructors private, which would be annoying. |
410 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); | 453 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); |
454 | |||
455 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
456 | pub enum GenericDefId { | ||
457 | FunctionId(FunctionId), | ||
458 | AdtId(AdtId), | ||
459 | TraitId(TraitId), | ||
460 | TypeAliasId(TypeAliasId), | ||
461 | ImplId(ImplId), | ||
462 | // enum variants cannot have generics themselves, but their parent enums | ||
463 | // can, and this makes some code easier to write | ||
464 | EnumVariantId(EnumVariantId), | ||
465 | // consts can have type parameters from their parents (i.e. associated consts of traits) | ||
466 | ConstId(ConstId), | ||
467 | } | ||
468 | impl_froms!( | ||
469 | GenericDefId: FunctionId, | ||
470 | AdtId(StructId, EnumId, UnionId), | ||
471 | TraitId, | ||
472 | TypeAliasId, | ||
473 | ImplId, | ||
474 | EnumVariantId, | ||
475 | ConstId | ||
476 | ); | ||
477 | |||
478 | trait Intern { | ||
479 | type ID; | ||
480 | fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; | ||
481 | } | ||
482 | |||
483 | pub trait Lookup { | ||
484 | type Data; | ||
485 | fn lookup(&self, db: &impl db::DefDatabase2) -> Self::Data; | ||
486 | } | ||
487 | |||
488 | pub trait HasModule { | ||
489 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId; | ||
490 | } | ||
491 | |||
492 | impl HasModule for FunctionLoc { | ||
493 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
494 | match self.container { | ||
495 | ContainerId::ModuleId(it) => it, | ||
496 | ContainerId::ImplId(it) => it.module(db), | ||
497 | ContainerId::TraitId(it) => it.module(db), | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | |||
502 | impl HasModule for TypeAliasLoc { | ||
503 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
504 | match self.container { | ||
505 | ContainerId::ModuleId(it) => it, | ||
506 | ContainerId::ImplId(it) => it.module(db), | ||
507 | ContainerId::TraitId(it) => it.module(db), | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | |||
512 | impl HasModule for ConstLoc { | ||
513 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
514 | match self.container { | ||
515 | ContainerId::ModuleId(it) => it, | ||
516 | ContainerId::ImplId(it) => it.module(db), | ||
517 | ContainerId::TraitId(it) => it.module(db), | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | |||
522 | pub trait HasSource { | ||
523 | type Value; | ||
524 | fn source(&self, db: &impl db::DefDatabase2) -> Source<Self::Value>; | ||
525 | } | ||
526 | |||
527 | impl HasSource for FunctionLoc { | ||
528 | type Value = ast::FnDef; | ||
529 | |||
530 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::FnDef> { | ||
531 | let node = self.ast_id.to_node(db); | ||
532 | Source::new(self.ast_id.file_id(), node) | ||
533 | } | ||
534 | } | ||
535 | |||
536 | impl HasSource for TypeAliasLoc { | ||
537 | type Value = ast::TypeAliasDef; | ||
538 | |||
539 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::TypeAliasDef> { | ||
540 | let node = self.ast_id.to_node(db); | ||
541 | Source::new(self.ast_id.file_id(), node) | ||
542 | } | ||
543 | } | ||
544 | |||
545 | impl HasSource for ConstLoc { | ||
546 | type Value = ast::ConstDef; | ||
547 | |||
548 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::ConstDef> { | ||
549 | let node = self.ast_id.to_node(db); | ||
550 | Source::new(self.ast_id.file_id(), node) | ||
551 | } | ||
552 | } | ||