diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 32 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/traits.rs | 82 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_def/src/impls.rs (renamed from crates/ra_hir_def/src/imp.rs) | 0 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir_def/src/traits.rs | 67 |
10 files changed, 103 insertions, 117 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index cb990f4e2..f436d5d5e 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -10,8 +10,9 @@ use hir_def::{ | |||
10 | adt::VariantData, | 10 | adt::VariantData, |
11 | body::scope::ExprScopes, | 11 | body::scope::ExprScopes, |
12 | builtin_type::BuiltinType, | 12 | builtin_type::BuiltinType, |
13 | traits::TraitData, | ||
13 | type_ref::{Mutability, TypeRef}, | 14 | type_ref::{Mutability, TypeRef}, |
14 | CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, | 15 | AssocItemId, CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, |
15 | }; | 16 | }; |
16 | use hir_expand::{ | 17 | use hir_expand::{ |
17 | diagnostics::DiagnosticSink, | 18 | diagnostics::DiagnosticSink, |
@@ -30,7 +31,6 @@ use crate::{ | |||
30 | TypeAliasId, | 31 | TypeAliasId, |
31 | }, | 32 | }, |
32 | resolve::{Resolver, Scope, TypeNs}, | 33 | resolve::{Resolver, Scope, TypeNs}, |
33 | traits::TraitData, | ||
34 | ty::{InferenceResult, Namespace, TraitRef}, | 34 | ty::{InferenceResult, Namespace, TraitRef}, |
35 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, | 35 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, |
36 | }; | 36 | }; |
@@ -230,15 +230,7 @@ impl Module { | |||
230 | 230 | ||
231 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { | 231 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { |
232 | let def_map = db.crate_def_map(self.id.krate); | 232 | let def_map = db.crate_def_map(self.id.krate); |
233 | def_map[self.id.module_id] | 233 | def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() |
234 | .scope | ||
235 | .entries() | ||
236 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) | ||
237 | .flat_map(|per_ns| { | ||
238 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
239 | }) | ||
240 | .map(ModuleDef::from) | ||
241 | .collect() | ||
242 | } | 234 | } |
243 | 235 | ||
244 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { | 236 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { |
@@ -693,7 +685,7 @@ impl Function { | |||
693 | 685 | ||
694 | /// The containing trait, if this is a trait method definition. | 686 | /// The containing trait, if this is a trait method definition. |
695 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 687 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
696 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 688 | db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) |
697 | } | 689 | } |
698 | 690 | ||
699 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 691 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
@@ -757,7 +749,7 @@ impl Const { | |||
757 | } | 749 | } |
758 | 750 | ||
759 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 751 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
760 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 752 | db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) |
761 | } | 753 | } |
762 | 754 | ||
763 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 755 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
@@ -861,11 +853,11 @@ impl Trait { | |||
861 | } | 853 | } |
862 | 854 | ||
863 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 855 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
864 | self.trait_data(db).name().clone() | 856 | self.trait_data(db).name.clone() |
865 | } | 857 | } |
866 | 858 | ||
867 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 859 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
868 | self.trait_data(db).items().to_vec() | 860 | self.trait_data(db).items.iter().map(|it| (*it).into()).collect() |
869 | } | 861 | } |
870 | 862 | ||
871 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | 863 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { |
@@ -912,10 +904,10 @@ impl Trait { | |||
912 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | 904 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { |
913 | let trait_data = self.trait_data(db); | 905 | let trait_data = self.trait_data(db); |
914 | trait_data | 906 | trait_data |
915 | .items() | 907 | .items |
916 | .iter() | 908 | .iter() |
917 | .filter_map(|item| match item { | 909 | .filter_map(|item| match item { |
918 | AssocItem::TypeAlias(t) => Some(*t), | 910 | AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)), |
919 | _ => None, | 911 | _ => None, |
920 | }) | 912 | }) |
921 | .find(|t| &t.name(db) == name) | 913 | .find(|t| &t.name(db) == name) |
@@ -930,7 +922,7 @@ impl Trait { | |||
930 | } | 922 | } |
931 | 923 | ||
932 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { | 924 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { |
933 | db.trait_data(self) | 925 | db.trait_data(self.id) |
934 | } | 926 | } |
935 | 927 | ||
936 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | 928 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { |
@@ -938,7 +930,7 @@ impl Trait { | |||
938 | } | 930 | } |
939 | 931 | ||
940 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | 932 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { |
941 | self.trait_data(db).is_auto() | 933 | self.trait_data(db).auto |
942 | } | 934 | } |
943 | 935 | ||
944 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { | 936 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { |
@@ -971,7 +963,7 @@ impl TypeAlias { | |||
971 | 963 | ||
972 | /// The containing trait, if this is a trait method definition. | 964 | /// The containing trait, if this is a trait method definition. |
973 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 965 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
974 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 966 | db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) |
975 | } | 967 | } |
976 | 968 | ||
977 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 969 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 0d35014a0..73859e1e9 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -11,7 +11,6 @@ use crate::{ | |||
11 | generics::{GenericDef, GenericParams}, | 11 | generics::{GenericDef, GenericParams}, |
12 | ids, | 12 | ids, |
13 | lang_item::{LangItemTarget, LangItems}, | 13 | lang_item::{LangItemTarget, LangItems}, |
14 | traits::TraitData, | ||
15 | ty::{ | 14 | ty::{ |
16 | method_resolution::CrateImplBlocks, | 15 | method_resolution::CrateImplBlocks, |
17 | traits::{AssocTyValue, Impl}, | 16 | traits::{AssocTyValue, Impl}, |
@@ -26,7 +25,8 @@ use crate::{ | |||
26 | pub use hir_def::db::{ | 25 | pub use hir_def::db::{ |
27 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, | 26 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, |
28 | EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, | 27 | EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, |
29 | RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, | 28 | RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery, |
29 | TraitItemsIndexQuery, | ||
30 | }; | 30 | }; |
31 | pub use hir_expand::db::{ | 31 | pub use hir_expand::db::{ |
32 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 32 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
@@ -37,12 +37,6 @@ pub use hir_expand::db::{ | |||
37 | #[salsa::query_group(DefDatabaseStorage)] | 37 | #[salsa::query_group(DefDatabaseStorage)] |
38 | #[salsa::requires(AstDatabase)] | 38 | #[salsa::requires(AstDatabase)] |
39 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | 39 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { |
40 | #[salsa::invoke(crate::traits::TraitData::trait_data_query)] | ||
41 | fn trait_data(&self, t: Trait) -> Arc<TraitData>; | ||
42 | |||
43 | #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] | ||
44 | fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; | ||
45 | |||
46 | #[salsa::invoke(crate::generics::generic_params_query)] | 40 | #[salsa::invoke(crate::generics::generic_params_query)] |
47 | fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>; | 41 | fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>; |
48 | 42 | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index da33c9591..7ac9a9041 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -33,7 +33,6 @@ pub mod source_binder; | |||
33 | 33 | ||
34 | mod ids; | 34 | mod ids; |
35 | mod adt; | 35 | mod adt; |
36 | mod traits; | ||
37 | mod type_alias; | 36 | mod type_alias; |
38 | mod ty; | 37 | mod ty; |
39 | mod impl_block; | 38 | mod impl_block; |
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs deleted file mode 100644 index 858972c6f..000000000 --- a/crates/ra_hir/src/traits.rs +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | //! HIR for trait definitions. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::name::AsName; | ||
6 | |||
7 | use ra_syntax::ast::{self, NameOwner}; | ||
8 | use rustc_hash::FxHashMap; | ||
9 | |||
10 | use crate::{ | ||
11 | db::{AstDatabase, DefDatabase}, | ||
12 | ids::LocationCtx, | ||
13 | AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias, | ||
14 | }; | ||
15 | |||
16 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
17 | pub struct TraitData { | ||
18 | name: Option<Name>, | ||
19 | items: Vec<AssocItem>, | ||
20 | auto: bool, | ||
21 | } | ||
22 | |||
23 | impl TraitData { | ||
24 | pub(crate) fn trait_data_query( | ||
25 | db: &(impl DefDatabase + AstDatabase), | ||
26 | tr: Trait, | ||
27 | ) -> Arc<TraitData> { | ||
28 | let src = tr.source(db); | ||
29 | let name = src.value.name().map(|n| n.as_name()); | ||
30 | let module = tr.module(db); | ||
31 | let ctx = LocationCtx::new(db, module.id, src.file_id); | ||
32 | let auto = src.value.is_auto(); | ||
33 | let items = if let Some(item_list) = src.value.item_list() { | ||
34 | item_list | ||
35 | .impl_items() | ||
36 | .map(|item_node| match item_node { | ||
37 | ast::ImplItem::FnDef(it) => Function { id: ctx.to_def(&it) }.into(), | ||
38 | ast::ImplItem::ConstDef(it) => Const { id: ctx.to_def(&it) }.into(), | ||
39 | ast::ImplItem::TypeAliasDef(it) => TypeAlias { id: ctx.to_def(&it) }.into(), | ||
40 | }) | ||
41 | .collect() | ||
42 | } else { | ||
43 | Vec::new() | ||
44 | }; | ||
45 | Arc::new(TraitData { name, items, auto }) | ||
46 | } | ||
47 | |||
48 | pub(crate) fn name(&self) -> &Option<Name> { | ||
49 | &self.name | ||
50 | } | ||
51 | |||
52 | pub(crate) fn items(&self) -> &[AssocItem] { | ||
53 | &self.items | ||
54 | } | ||
55 | |||
56 | pub(crate) fn is_auto(&self) -> bool { | ||
57 | self.auto | ||
58 | } | ||
59 | } | ||
60 | |||
61 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
62 | pub struct TraitItemsIndex { | ||
63 | traits_by_def: FxHashMap<AssocItem, Trait>, | ||
64 | } | ||
65 | |||
66 | impl TraitItemsIndex { | ||
67 | pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { | ||
68 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; | ||
69 | for decl in module.declarations(db) { | ||
70 | if let crate::ModuleDef::Trait(tr) = decl { | ||
71 | for item in tr.trait_data(db).items() { | ||
72 | index.traits_by_def.insert(*item, tr); | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | index | ||
77 | } | ||
78 | |||
79 | pub(crate) fn get_parent_trait(&self, item: AssocItem) -> Option<Trait> { | ||
80 | self.traits_by_def.get(&item).cloned() | ||
81 | } | ||
82 | } | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index d20aeaacf..f377fca48 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -232,8 +232,8 @@ fn iterate_trait_method_candidates<T>( | |||
232 | // trait, but if we find out it doesn't, we'll skip the rest of the | 232 | // trait, but if we find out it doesn't, we'll skip the rest of the |
233 | // iteration | 233 | // iteration |
234 | let mut known_implemented = false; | 234 | let mut known_implemented = false; |
235 | for &item in data.items() { | 235 | for &item in data.items.iter() { |
236 | if !is_valid_candidate(db, name, mode, item) { | 236 | if !is_valid_candidate(db, name, mode, item.into()) { |
237 | continue; | 237 | continue; |
238 | } | 238 | } |
239 | if !known_implemented { | 239 | if !known_implemented { |
@@ -243,7 +243,7 @@ fn iterate_trait_method_candidates<T>( | |||
243 | } | 243 | } |
244 | } | 244 | } |
245 | known_implemented = true; | 245 | known_implemented = true; |
246 | if let Some(result) = callback(&ty.value, item) { | 246 | if let Some(result) = callback(&ty.value, item.into()) { |
247 | return Some(result); | 247 | return Some(result); |
248 | } | 248 | } |
249 | } | 249 | } |
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 348aca07f..fb4402463 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -8,12 +8,13 @@ use ra_syntax::ast; | |||
8 | use crate::{ | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | 9 | adt::{EnumData, StructData}, |
10 | body::{scope::ExprScopes, Body, BodySourceMap}, | 10 | body::{scope::ExprScopes, Body, BodySourceMap}, |
11 | imp::ImplData, | 11 | impls::ImplData, |
12 | nameres::{ | 12 | nameres::{ |
13 | raw::{ImportSourceMap, RawItems}, | 13 | raw::{ImportSourceMap, RawItems}, |
14 | CrateDefMap, | 14 | CrateDefMap, |
15 | }, | 15 | }, |
16 | DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, | 16 | traits::{TraitData, TraitItemsIndex}, |
17 | DefWithBodyId, EnumId, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId, | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | #[salsa::query_group(InternDatabaseStorage)] | 20 | #[salsa::query_group(InternDatabaseStorage)] |
@@ -59,6 +60,12 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
59 | #[salsa::invoke(ImplData::impl_data_query)] | 60 | #[salsa::invoke(ImplData::impl_data_query)] |
60 | fn impl_data(&self, e: ImplId) -> Arc<ImplData>; | 61 | fn impl_data(&self, e: ImplId) -> Arc<ImplData>; |
61 | 62 | ||
63 | #[salsa::invoke(TraitData::trait_data_query)] | ||
64 | fn trait_data(&self, e: TraitId) -> Arc<TraitData>; | ||
65 | |||
66 | #[salsa::invoke(TraitItemsIndex::trait_items_index)] | ||
67 | fn trait_items_index(&self, module: ModuleId) -> TraitItemsIndex; | ||
68 | |||
62 | #[salsa::invoke(Body::body_with_source_map_query)] | 69 | #[salsa::invoke(Body::body_with_source_map_query)] |
63 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); | 70 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); |
64 | 71 | ||
diff --git a/crates/ra_hir_def/src/imp.rs b/crates/ra_hir_def/src/impls.rs index 4323dfcb6..4323dfcb6 100644 --- a/crates/ra_hir_def/src/imp.rs +++ b/crates/ra_hir_def/src/impls.rs | |||
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index dffc82ff8..38c110570 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -13,11 +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; | 20 | pub mod generics; |
21 | pub mod traits; | ||
21 | 22 | ||
22 | #[cfg(test)] | 23 | #[cfg(test)] |
23 | mod test_db; | 24 | mod test_db; |
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index e5b073a0f..c01e020ef 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -165,6 +165,14 @@ impl ModuleScope { | |||
165 | self.items.iter().chain(BUILTIN_SCOPE.iter()) | 165 | self.items.iter().chain(BUILTIN_SCOPE.iter()) |
166 | } | 166 | } |
167 | 167 | ||
168 | pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ { | ||
169 | self.entries() | ||
170 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) | ||
171 | .flat_map(|per_ns| { | ||
172 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
173 | }) | ||
174 | } | ||
175 | |||
168 | /// Iterate over all module scoped macros | 176 | /// Iterate over all module scoped macros |
169 | pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { | 177 | pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { |
170 | self.items | 178 | self.items |
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs new file mode 100644 index 000000000..a8ba31594 --- /dev/null +++ b/crates/ra_hir_def/src/traits.rs | |||
@@ -0,0 +1,67 @@ | |||
1 | //! HIR for trait definitions. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::name::{AsName, Name}; | ||
6 | |||
7 | use ra_syntax::ast::{self, NameOwner}; | ||
8 | use rustc_hash::FxHashMap; | ||
9 | |||
10 | use crate::{ | ||
11 | db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionId, LocationCtx, ModuleDefId, | ||
12 | ModuleId, TraitId, TypeAliasId, | ||
13 | }; | ||
14 | |||
15 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
16 | pub struct TraitData { | ||
17 | pub name: Option<Name>, | ||
18 | pub items: Vec<AssocItemId>, | ||
19 | pub auto: bool, | ||
20 | } | ||
21 | |||
22 | impl TraitData { | ||
23 | pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> { | ||
24 | let src = tr.source(db); | ||
25 | let name = src.value.name().map(|n| n.as_name()); | ||
26 | let module = tr.module(db); | ||
27 | let ctx = LocationCtx::new(db, module, src.file_id); | ||
28 | let auto = src.value.is_auto(); | ||
29 | let items = if let Some(item_list) = src.value.item_list() { | ||
30 | item_list | ||
31 | .impl_items() | ||
32 | .map(|item_node| match item_node { | ||
33 | ast::ImplItem::FnDef(it) => FunctionId::from_ast(ctx, &it).into(), | ||
34 | ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), | ||
35 | ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(), | ||
36 | }) | ||
37 | .collect() | ||
38 | } else { | ||
39 | Vec::new() | ||
40 | }; | ||
41 | Arc::new(TraitData { name, items, auto }) | ||
42 | } | ||
43 | } | ||
44 | |||
45 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
46 | pub struct TraitItemsIndex { | ||
47 | traits_by_def: FxHashMap<AssocItemId, TraitId>, | ||
48 | } | ||
49 | |||
50 | impl TraitItemsIndex { | ||
51 | pub fn trait_items_index(db: &impl DefDatabase2, module: ModuleId) -> TraitItemsIndex { | ||
52 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; | ||
53 | let crate_def_map = db.crate_def_map(module.krate); | ||
54 | for decl in crate_def_map[module.module_id].scope.declarations() { | ||
55 | if let ModuleDefId::TraitId(tr) = decl { | ||
56 | for item in db.trait_data(tr).items.iter() { | ||
57 | index.traits_by_def.insert(*item, tr); | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | index | ||
62 | } | ||
63 | |||
64 | pub fn get_parent_trait(&self, item: AssocItemId) -> Option<TraitId> { | ||
65 | self.traits_by_def.get(&item).cloned() | ||
66 | } | ||
67 | } | ||