diff options
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 114 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 17 |
3 files changed, 142 insertions, 1 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs new file mode 100644 index 000000000..22bd469f0 --- /dev/null +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -0,0 +1,114 @@ | |||
1 | //! Defines hir-level representation of structs, enums and unions | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::name::{AsName, Name}; | ||
6 | use ra_arena::Arena; | ||
7 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | ||
8 | |||
9 | use crate::{ | ||
10 | db::DefDatabase2, type_ref::TypeRef, AstItemDef, EnumId, LocalEnumVariantId, | ||
11 | LocalStructFieldId, StructId, | ||
12 | }; | ||
13 | |||
14 | /// Note that we use `StructData` for unions as well! | ||
15 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
16 | pub struct StructData { | ||
17 | pub name: Option<Name>, | ||
18 | pub variant_data: Arc<VariantData>, | ||
19 | } | ||
20 | |||
21 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
22 | pub struct EnumData { | ||
23 | pub name: Option<Name>, | ||
24 | pub variants: Arena<LocalEnumVariantId, EnumVariantData>, | ||
25 | } | ||
26 | |||
27 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
28 | pub struct EnumVariantData { | ||
29 | pub name: Option<Name>, | ||
30 | pub variant_data: Arc<VariantData>, | ||
31 | } | ||
32 | |||
33 | /// Fields of an enum variant or struct | ||
34 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
35 | pub struct VariantData(VariantDataInner); | ||
36 | |||
37 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
38 | enum VariantDataInner { | ||
39 | Struct(Arena<LocalStructFieldId, StructFieldData>), | ||
40 | Tuple(Arena<LocalStructFieldId, StructFieldData>), | ||
41 | Unit, | ||
42 | } | ||
43 | |||
44 | /// A single field of an enum variant or struct | ||
45 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
46 | pub struct StructFieldData { | ||
47 | pub name: Name, | ||
48 | pub type_ref: TypeRef, | ||
49 | } | ||
50 | |||
51 | impl StructData { | ||
52 | pub(crate) fn struct_data_query(db: &impl DefDatabase2, struct_: StructId) -> Arc<StructData> { | ||
53 | let src = struct_.source(db); | ||
54 | let name = src.ast.name().map(|n| n.as_name()); | ||
55 | let variant_data = VariantData::new(src.ast.kind()); | ||
56 | let variant_data = Arc::new(variant_data); | ||
57 | Arc::new(StructData { name, variant_data }) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | impl EnumData { | ||
62 | pub(crate) fn enum_data_query(db: &impl DefDatabase2, e: EnumId) -> Arc<EnumData> { | ||
63 | let src = e.source(db); | ||
64 | let name = src.ast.name().map(|n| n.as_name()); | ||
65 | let variants = src | ||
66 | .ast | ||
67 | .variant_list() | ||
68 | .into_iter() | ||
69 | .flat_map(|it| it.variants()) | ||
70 | .map(|var| EnumVariantData { | ||
71 | name: var.name().map(|it| it.as_name()), | ||
72 | variant_data: Arc::new(VariantData::new(var.kind())), | ||
73 | }) | ||
74 | .collect(); | ||
75 | Arc::new(EnumData { name, variants }) | ||
76 | } | ||
77 | } | ||
78 | |||
79 | impl VariantData { | ||
80 | fn new(flavor: ast::StructKind) -> Self { | ||
81 | let inner = match flavor { | ||
82 | ast::StructKind::Tuple(fl) => { | ||
83 | let fields = fl | ||
84 | .fields() | ||
85 | .enumerate() | ||
86 | .map(|(i, fd)| StructFieldData { | ||
87 | name: Name::new_tuple_field(i), | ||
88 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), | ||
89 | }) | ||
90 | .collect(); | ||
91 | VariantDataInner::Tuple(fields) | ||
92 | } | ||
93 | ast::StructKind::Named(fl) => { | ||
94 | let fields = fl | ||
95 | .fields() | ||
96 | .map(|fd| StructFieldData { | ||
97 | name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), | ||
98 | type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), | ||
99 | }) | ||
100 | .collect(); | ||
101 | VariantDataInner::Struct(fields) | ||
102 | } | ||
103 | ast::StructKind::Unit => VariantDataInner::Unit, | ||
104 | }; | ||
105 | VariantData(inner) | ||
106 | } | ||
107 | |||
108 | pub fn fields(&self) -> Option<&Arena<LocalStructFieldId, StructFieldData>> { | ||
109 | match &self.0 { | ||
110 | VariantDataInner::Struct(fields) | VariantDataInner::Tuple(fields) => Some(fields), | ||
111 | _ => None, | ||
112 | } | ||
113 | } | ||
114 | } | ||
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index b271636b0..f6027013f 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -5,7 +5,11 @@ use hir_expand::{db::AstDatabase, HirFileId}; | |||
5 | use ra_db::{salsa, SourceDatabase}; | 5 | use ra_db::{salsa, SourceDatabase}; |
6 | use ra_syntax::ast; | 6 | use ra_syntax::ast; |
7 | 7 | ||
8 | use crate::nameres::raw::{ImportSourceMap, RawItems}; | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | ||
10 | nameres::raw::{ImportSourceMap, RawItems}, | ||
11 | EnumId, StructId, | ||
12 | }; | ||
9 | 13 | ||
10 | #[salsa::query_group(InternDatabaseStorage)] | 14 | #[salsa::query_group(InternDatabaseStorage)] |
11 | pub trait InternDatabase: SourceDatabase { | 15 | pub trait InternDatabase: SourceDatabase { |
@@ -37,4 +41,10 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
37 | 41 | ||
38 | #[salsa::invoke(RawItems::raw_items_query)] | 42 | #[salsa::invoke(RawItems::raw_items_query)] |
39 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; | 43 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; |
44 | |||
45 | #[salsa::invoke(StructData::struct_data_query)] | ||
46 | fn struct_data(&self, s: StructId) -> Arc<StructData>; | ||
47 | |||
48 | #[salsa::invoke(EnumData::enum_data_query)] | ||
49 | fn enum_data(&self, e: EnumId) -> Arc<EnumData>; | ||
40 | } | 50 | } |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 93ad40005..76d5f1852 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -12,6 +12,7 @@ pub mod attr; | |||
12 | pub mod path; | 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 | 16 | ||
16 | // FIXME: this should be private | 17 | // FIXME: this should be private |
17 | pub mod nameres; | 18 | pub mod nameres; |
@@ -260,6 +261,22 @@ pub struct LocalEnumVariantId(RawId); | |||
260 | impl_arena_id!(LocalEnumVariantId); | 261 | impl_arena_id!(LocalEnumVariantId); |
261 | 262 | ||
262 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 263 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
264 | pub enum VariantId { | ||
265 | EnumVariantId(EnumVariantId), | ||
266 | StructId(StructId), | ||
267 | } | ||
268 | |||
269 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
270 | pub struct StructFieldId { | ||
271 | parent: VariantId, | ||
272 | local_id: LocalStructFieldId, | ||
273 | } | ||
274 | |||
275 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
276 | pub struct LocalStructFieldId(RawId); | ||
277 | impl_arena_id!(LocalStructFieldId); | ||
278 | |||
279 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
263 | pub struct ConstId(salsa::InternId); | 280 | pub struct ConstId(salsa::InternId); |
264 | impl_intern_key!(ConstId); | 281 | impl_intern_key!(ConstId); |
265 | impl AstItemDef<ast::ConstDef> for ConstId { | 282 | impl AstItemDef<ast::ConstDef> for ConstId { |