aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/impls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/impls.rs')
-rw-r--r--crates/ra_hir_def/src/impls.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/crates/ra_hir_def/src/impls.rs b/crates/ra_hir_def/src/impls.rs
new file mode 100644
index 000000000..4323dfcb6
--- /dev/null
+++ b/crates/ra_hir_def/src/impls.rs
@@ -0,0 +1,71 @@
1//! Defines hir-level representation of impls.
2//!
3//! The handling is similar, but is not quite the same as for other items,
4//! because `impl`s don't have names.
5
6use std::sync::Arc;
7
8use ra_syntax::ast;
9
10use crate::{
11 db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionId, ImplId,
12 LocationCtx, TypeAliasId,
13};
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct ImplData {
17 target_trait: Option<TypeRef>,
18 target_type: TypeRef,
19 items: Vec<AssocItemId>,
20 negative: bool,
21}
22
23impl ImplData {
24 pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc<ImplData> {
25 let src = id.source(db);
26 let items = db.ast_id_map(src.file_id);
27
28 let target_trait = src.value.target_trait().map(TypeRef::from_ast);
29 let target_type = TypeRef::from_ast_opt(src.value.target_type());
30 let negative = src.value.is_negative();
31
32 let items = if let Some(item_list) = src.value.item_list() {
33 let ctx = LocationCtx::new(db, id.module(db), src.file_id);
34 item_list
35 .impl_items()
36 .map(|item_node| match item_node {
37 ast::ImplItem::FnDef(it) => {
38 FunctionId::from_ast_id(ctx, items.ast_id(&it)).into()
39 }
40 ast::ImplItem::ConstDef(it) => {
41 ConstId::from_ast_id(ctx, items.ast_id(&it)).into()
42 }
43 ast::ImplItem::TypeAliasDef(it) => {
44 TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into()
45 }
46 })
47 .collect()
48 } else {
49 Vec::new()
50 };
51
52 let res = ImplData { target_trait, target_type, items, negative };
53 Arc::new(res)
54 }
55
56 pub fn target_trait(&self) -> Option<&TypeRef> {
57 self.target_trait.as_ref()
58 }
59
60 pub fn target_type(&self) -> &TypeRef {
61 &self.target_type
62 }
63
64 pub fn items(&self) -> &[AssocItemId] {
65 &self.items
66 }
67
68 pub fn is_negative(&self) -> bool {
69 self.negative
70 }
71}