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/adt.rs114
-rw-r--r--crates/ra_hir_def/src/db.rs12
-rw-r--r--crates/ra_hir_def/src/lib.rs17
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
3use std::sync::Arc;
4
5use hir_expand::name::{AsName, Name};
6use ra_arena::Arena;
7use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
8
9use 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)]
16pub struct StructData {
17 pub name: Option<Name>,
18 pub variant_data: Arc<VariantData>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct EnumData {
23 pub name: Option<Name>,
24 pub variants: Arena<LocalEnumVariantId, EnumVariantData>,
25}
26
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub 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)]
35pub struct VariantData(VariantDataInner);
36
37#[derive(Debug, Clone, PartialEq, Eq)]
38enum 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)]
46pub struct StructFieldData {
47 pub name: Name,
48 pub type_ref: TypeRef,
49}
50
51impl 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
61impl 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
79impl 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};
5use ra_db::{salsa, SourceDatabase}; 5use ra_db::{salsa, SourceDatabase};
6use ra_syntax::ast; 6use ra_syntax::ast;
7 7
8use crate::nameres::raw::{ImportSourceMap, RawItems}; 8use 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)]
11pub trait InternDatabase: SourceDatabase { 15pub 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;
12pub mod path; 12pub mod path;
13pub mod type_ref; 13pub mod type_ref;
14pub mod builtin_type; 14pub mod builtin_type;
15pub mod adt;
15 16
16// FIXME: this should be private 17// FIXME: this should be private
17pub mod nameres; 18pub mod nameres;
@@ -260,6 +261,22 @@ pub struct LocalEnumVariantId(RawId);
260impl_arena_id!(LocalEnumVariantId); 261impl_arena_id!(LocalEnumVariantId);
261 262
262#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 263#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
264pub enum VariantId {
265 EnumVariantId(EnumVariantId),
266 StructId(StructId),
267}
268
269#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
270pub struct StructFieldId {
271 parent: VariantId,
272 local_id: LocalStructFieldId,
273}
274
275#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
276pub struct LocalStructFieldId(RawId);
277impl_arena_id!(LocalStructFieldId);
278
279#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
263pub struct ConstId(salsa::InternId); 280pub struct ConstId(salsa::InternId);
264impl_intern_key!(ConstId); 281impl_intern_key!(ConstId);
265impl AstItemDef<ast::ConstDef> for ConstId { 282impl AstItemDef<ast::ConstDef> for ConstId {