diff options
Diffstat (limited to 'crates/ra_hir_def/src/traits.rs')
-rw-r--r-- | crates/ra_hir_def/src/traits.rs | 67 |
1 files changed, 67 insertions, 0 deletions
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 | } | ||