diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 70 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 8 |
2 files changed, 64 insertions, 14 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 4d9641728..4fb679f6d 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -10,9 +10,9 @@ use hir_def::{ | |||
10 | per_ns::PerNs, | 10 | per_ns::PerNs, |
11 | resolver::HasResolver, | 11 | resolver::HasResolver, |
12 | type_ref::{Mutability, TypeRef}, | 12 | type_ref::{Mutability, TypeRef}, |
13 | AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, | 13 | AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, |
14 | LocalEnumVariantId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, | 14 | ImplId, LocalEnumVariantId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, |
15 | TraitId, TypeAliasId, TypeParamId, UnionId, | 15 | StructId, TraitId, TypeAliasId, TypeParamId, UnionId, |
16 | }; | 16 | }; |
17 | use hir_expand::{ | 17 | use hir_expand::{ |
18 | diagnostics::DiagnosticSink, | 18 | diagnostics::DiagnosticSink, |
@@ -25,7 +25,10 @@ use hir_ty::{ | |||
25 | }; | 25 | }; |
26 | use ra_db::{CrateId, Edition, FileId}; | 26 | use ra_db::{CrateId, Edition, FileId}; |
27 | use ra_prof::profile; | 27 | use ra_prof::profile; |
28 | use ra_syntax::ast::{self, AttrsOwner}; | 28 | use ra_syntax::{ |
29 | ast::{self, AttrsOwner}, | ||
30 | AstNode, | ||
31 | }; | ||
29 | 32 | ||
30 | use crate::{ | 33 | use crate::{ |
31 | db::{DefDatabase, HirDatabase}, | 34 | db::{DefDatabase, HirDatabase}, |
@@ -119,7 +122,9 @@ impl_froms!( | |||
119 | BuiltinType | 122 | BuiltinType |
120 | ); | 123 | ); |
121 | 124 | ||
122 | pub use hir_def::{attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId}; | 125 | pub use hir_def::{ |
126 | attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc, | ||
127 | }; | ||
123 | use rustc_hash::FxHashSet; | 128 | use rustc_hash::FxHashSet; |
124 | 129 | ||
125 | impl Module { | 130 | impl Module { |
@@ -639,17 +644,49 @@ pub struct MacroDef { | |||
639 | pub(crate) id: MacroDefId, | 644 | pub(crate) id: MacroDefId, |
640 | } | 645 | } |
641 | 646 | ||
647 | /// Invariant: `inner.as_assoc_item(db).is_some()` | ||
648 | /// We do not actively enforce this invariant. | ||
642 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 649 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
643 | pub enum AssocItem { | 650 | pub enum AssocItem { |
644 | Function(Function), | 651 | Function(Function), |
645 | Const(Const), | 652 | Const(Const), |
646 | TypeAlias(TypeAlias), | 653 | TypeAlias(TypeAlias), |
647 | } | 654 | } |
648 | // FIXME: not every function, ... is actually an assoc item. maybe we should make | 655 | pub enum AssocItemContainer { |
649 | // sure that you can only turn actual assoc items into AssocItems. This would | 656 | Trait(Trait), |
650 | // require not implementing From, and instead having some checked way of | 657 | ImplBlock(ImplBlock), |
651 | // casting them, and somehow making the constructors private, which would be annoying. | 658 | } |
652 | impl_froms!(AssocItem: Function, Const, TypeAlias); | 659 | pub trait AsAssocItem { |
660 | fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem>; | ||
661 | } | ||
662 | |||
663 | impl AsAssocItem for Function { | ||
664 | fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem> { | ||
665 | as_assoc_item(db, AssocItem::Function, self.id) | ||
666 | } | ||
667 | } | ||
668 | impl AsAssocItem for Const { | ||
669 | fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem> { | ||
670 | as_assoc_item(db, AssocItem::Const, self.id) | ||
671 | } | ||
672 | } | ||
673 | impl AsAssocItem for TypeAlias { | ||
674 | fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem> { | ||
675 | as_assoc_item(db, AssocItem::TypeAlias, self.id) | ||
676 | } | ||
677 | } | ||
678 | fn as_assoc_item<ID, DEF, CTOR, AST>(db: &impl DefDatabase, ctor: CTOR, id: ID) -> Option<AssocItem> | ||
679 | where | ||
680 | ID: Lookup<Data = AssocItemLoc<AST>>, | ||
681 | DEF: From<ID>, | ||
682 | CTOR: FnOnce(DEF) -> AssocItem, | ||
683 | AST: AstNode, | ||
684 | { | ||
685 | match id.lookup(db).container { | ||
686 | AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))), | ||
687 | AssocContainerId::ContainerId(_) => None, | ||
688 | } | ||
689 | } | ||
653 | 690 | ||
654 | impl AssocItem { | 691 | impl AssocItem { |
655 | pub fn module(self, db: &impl DefDatabase) -> Module { | 692 | pub fn module(self, db: &impl DefDatabase) -> Module { |
@@ -659,6 +696,18 @@ impl AssocItem { | |||
659 | AssocItem::TypeAlias(t) => t.module(db), | 696 | AssocItem::TypeAlias(t) => t.module(db), |
660 | } | 697 | } |
661 | } | 698 | } |
699 | pub fn container(self, db: &impl DefDatabase) -> AssocItemContainer { | ||
700 | let container = match self { | ||
701 | AssocItem::Function(it) => it.id.lookup(db).container, | ||
702 | AssocItem::Const(it) => it.id.lookup(db).container, | ||
703 | AssocItem::TypeAlias(it) => it.id.lookup(db).container, | ||
704 | }; | ||
705 | match container { | ||
706 | AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), | ||
707 | AssocContainerId::ImplId(id) => AssocItemContainer::ImplBlock(id.into()), | ||
708 | AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"), | ||
709 | } | ||
710 | } | ||
662 | } | 711 | } |
663 | 712 | ||
664 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 713 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
@@ -769,6 +818,7 @@ impl TypeParam { | |||
769 | } | 818 | } |
770 | } | 819 | } |
771 | 820 | ||
821 | // FIXME: rename to `ImplBlock` | ||
772 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 822 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
773 | pub struct ImplBlock { | 823 | pub struct ImplBlock { |
774 | pub(crate) id: ImplId, | 824 | pub(crate) id: ImplId, |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index e1c7b7a20..5cd965f7a 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -39,10 +39,10 @@ mod has_source; | |||
39 | 39 | ||
40 | pub use crate::{ | 40 | pub use crate::{ |
41 | code_model::{ | 41 | code_model::{ |
42 | Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, | 42 | Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Const, Crate, CrateDependency, |
43 | EnumVariant, FieldSource, Function, GenericDef, HasAttrs, HasVisibility, ImplBlock, Local, | 43 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, HasAttrs, |
44 | MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, | 44 | HasVisibility, ImplBlock, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, |
45 | TypeParam, Union, VariantDef, | 45 | StructField, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, |
46 | }, | 46 | }, |
47 | has_source::HasSource, | 47 | has_source::HasSource, |
48 | source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 48 | source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |