aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/traits.rs')
-rw-r--r--crates/ra_hir_def/src/traits.rs67
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
3use std::sync::Arc;
4
5use hir_expand::name::{AsName, Name};
6
7use ra_syntax::ast::{self, NameOwner};
8use rustc_hash::FxHashMap;
9
10use crate::{
11 db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionId, LocationCtx, ModuleDefId,
12 ModuleId, TraitId, TypeAliasId,
13};
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct TraitData {
17 pub name: Option<Name>,
18 pub items: Vec<AssocItemId>,
19 pub auto: bool,
20}
21
22impl 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)]
46pub struct TraitItemsIndex {
47 traits_by_def: FxHashMap<AssocItemId, TraitId>,
48}
49
50impl 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}