aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/db.rs6
-rw-r--r--crates/ra_hir_def/src/imp.rs71
-rw-r--r--crates/ra_hir_def/src/lib.rs13
3 files changed, 89 insertions, 1 deletions
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 40e68a3c3..348aca07f 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -8,11 +8,12 @@ use ra_syntax::ast;
8use crate::{ 8use 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 nameres::{ 12 nameres::{
12 raw::{ImportSourceMap, RawItems}, 13 raw::{ImportSourceMap, RawItems},
13 CrateDefMap, 14 CrateDefMap,
14 }, 15 },
15 DefWithBodyId, EnumId, ItemLoc, StructOrUnionId, 16 DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId,
16}; 17};
17 18
18#[salsa::query_group(InternDatabaseStorage)] 19#[salsa::query_group(InternDatabaseStorage)]
@@ -55,6 +56,9 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
55 #[salsa::invoke(EnumData::enum_data_query)] 56 #[salsa::invoke(EnumData::enum_data_query)]
56 fn enum_data(&self, e: EnumId) -> Arc<EnumData>; 57 fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
57 58
59 #[salsa::invoke(ImplData::impl_data_query)]
60 fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
61
58 #[salsa::invoke(Body::body_with_source_map_query)] 62 #[salsa::invoke(Body::body_with_source_map_query)]
59 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); 63 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
60 64
diff --git a/crates/ra_hir_def/src/imp.rs b/crates/ra_hir_def/src/imp.rs
new file mode 100644
index 000000000..717991c40
--- /dev/null
+++ b/crates/ra_hir_def/src/imp.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.ast.target_trait().map(TypeRef::from_ast);
29 let target_type = TypeRef::from_ast_opt(src.ast.target_type());
30 let negative = src.ast.is_negative();
31
32 let items = if let Some(item_list) = src.ast.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}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 22650db8b..0a59c4ad7 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -13,6 +13,7 @@ pub mod path;
13pub mod type_ref; 13pub mod type_ref;
14pub mod builtin_type; 14pub mod builtin_type;
15pub mod adt; 15pub mod adt;
16pub mod imp;
16pub mod diagnostics; 17pub mod diagnostics;
17pub mod expr; 18pub mod expr;
18pub mod body; 19pub mod body;
@@ -396,3 +397,15 @@ pub enum DefWithBodyId {
396} 397}
397 398
398impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); 399impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId);
400
401#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
402pub enum AssocItemId {
403 FunctionId(FunctionId),
404 ConstId(ConstId),
405 TypeAliasId(TypeAliasId),
406}
407// FIXME: not every function, ... is actually an assoc item. maybe we should make
408// sure that you can only turn actual assoc items into AssocItemIds. This would
409// require not implementing From, and instead having some checked way of
410// casting them, and somehow making the constructors private, which would be annoying.
411impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId);