aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/adt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/adt.rs')
-rw-r--r--crates/ra_hir/src/adt.rs131
1 files changed, 30 insertions, 101 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index b75adda84..602e7db74 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -1,93 +1,60 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_db::Cancelable; 3use ra_db::Cancelable;
4use ra_syntax::ast::{self, NameOwner, StructFlavor}; 4use ra_syntax::ast::{self, NameOwner, StructFlavor, AstNode};
5 5
6use crate::{ 6use crate::{
7 DefId, Name, AsName, 7 DefId, Name, AsName, Struct, Enum, VariantData, StructField, HirDatabase, DefKind,
8 db::HirDatabase,
9 type_ref::TypeRef, 8 type_ref::TypeRef,
10}; 9};
11 10
12pub struct Struct {
13 def_id: DefId,
14}
15
16impl Struct { 11impl Struct {
17 pub(crate) fn new(def_id: DefId) -> Self { 12 pub(crate) fn new(def_id: DefId) -> Self {
18 Struct { def_id } 13 Struct { def_id }
19 } 14 }
20
21 pub fn def_id(&self) -> DefId {
22 self.def_id
23 }
24
25 pub fn variant_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<VariantData>> {
26 Ok(db.struct_data(self.def_id)?.variant_data.clone())
27 }
28
29 pub fn struct_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<StructData>> {
30 Ok(db.struct_data(self.def_id)?)
31 }
32
33 pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> {
34 Ok(db.struct_data(self.def_id)?.name.clone())
35 }
36} 15}
37 16
38#[derive(Debug, Clone, PartialEq, Eq)] 17#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct StructData { 18pub struct StructData {
40 name: Option<Name>, 19 pub(crate) name: Option<Name>,
41 variant_data: Arc<VariantData>, 20 pub(crate) variant_data: Arc<VariantData>,
42} 21}
43 22
44impl StructData { 23impl StructData {
45 pub(crate) fn new(struct_def: &ast::StructDef) -> StructData { 24 fn new(struct_def: &ast::StructDef) -> StructData {
46 let name = struct_def.name().map(|n| n.as_name()); 25 let name = struct_def.name().map(|n| n.as_name());
47 let variant_data = VariantData::new(struct_def.flavor()); 26 let variant_data = VariantData::new(struct_def.flavor());
48 let variant_data = Arc::new(variant_data); 27 let variant_data = Arc::new(variant_data);
49 StructData { name, variant_data } 28 StructData { name, variant_data }
50 } 29 }
51 30
52 pub fn name(&self) -> Option<&Name> { 31 pub(crate) fn struct_data_query(
53 self.name.as_ref() 32 db: &impl HirDatabase,
54 } 33 def_id: DefId,
55 34 ) -> Cancelable<Arc<StructData>> {
56 pub fn variant_data(&self) -> &Arc<VariantData> { 35 let def_loc = def_id.loc(db);
57 &self.variant_data 36 assert!(def_loc.kind == DefKind::Struct);
37 let syntax = db.file_item(def_loc.source_item_id);
38 let struct_def =
39 ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node");
40 Ok(Arc::new(StructData::new(struct_def)))
58 } 41 }
59} 42}
60 43
61pub struct Enum {
62 def_id: DefId,
63}
64
65impl Enum { 44impl Enum {
66 pub(crate) fn new(def_id: DefId) -> Self { 45 pub(crate) fn new(def_id: DefId) -> Self {
67 Enum { def_id } 46 Enum { def_id }
68 } 47 }
69
70 pub fn def_id(&self) -> DefId {
71 self.def_id
72 }
73
74 pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> {
75 Ok(db.enum_data(self.def_id)?.name.clone())
76 }
77
78 pub fn variants(&self, db: &impl HirDatabase) -> Cancelable<Vec<(Name, Arc<VariantData>)>> {
79 Ok(db.enum_data(self.def_id)?.variants.clone())
80 }
81} 48}
82 49
83#[derive(Debug, Clone, PartialEq, Eq)] 50#[derive(Debug, Clone, PartialEq, Eq)]
84pub struct EnumData { 51pub struct EnumData {
85 name: Option<Name>, 52 pub(crate) name: Option<Name>,
86 variants: Vec<(Name, Arc<VariantData>)>, 53 pub(crate) variants: Vec<(Name, Arc<VariantData>)>,
87} 54}
88 55
89impl EnumData { 56impl EnumData {
90 pub(crate) fn new(enum_def: &ast::EnumDef) -> Self { 57 fn new(enum_def: &ast::EnumDef) -> Self {
91 let name = enum_def.name().map(|n| n.as_name()); 58 let name = enum_def.name().map(|n| n.as_name());
92 let variants = if let Some(evl) = enum_def.variant_list() { 59 let variants = if let Some(evl) = enum_def.variant_list() {
93 evl.variants() 60 evl.variants()
@@ -103,34 +70,21 @@ impl EnumData {
103 }; 70 };
104 EnumData { name, variants } 71 EnumData { name, variants }
105 } 72 }
106}
107
108/// A single field of an enum variant or struct
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub struct StructField {
111 name: Name,
112 type_ref: TypeRef,
113}
114 73
115impl StructField { 74 pub(crate) fn enum_data_query(
116 pub fn name(&self) -> Name { 75 db: &impl HirDatabase,
117 self.name.clone() 76 def_id: DefId,
77 ) -> Cancelable<Arc<EnumData>> {
78 let def_loc = def_id.loc(db);
79 assert!(def_loc.kind == DefKind::Enum);
80 let syntax = db.file_item(def_loc.source_item_id);
81 let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
82 Ok(Arc::new(EnumData::new(enum_def)))
118 } 83 }
119 pub fn type_ref(&self) -> &TypeRef {
120 &self.type_ref
121 }
122}
123
124/// Fields of an enum variant or struct
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub enum VariantData {
127 Struct(Vec<StructField>),
128 Tuple(Vec<StructField>),
129 Unit,
130} 84}
131 85
132impl VariantData { 86impl VariantData {
133 pub fn new(flavor: StructFlavor) -> Self { 87 fn new(flavor: StructFlavor) -> Self {
134 match flavor { 88 match flavor {
135 StructFlavor::Tuple(fl) => { 89 StructFlavor::Tuple(fl) => {
136 let fields = fl 90 let fields = fl
@@ -160,32 +114,7 @@ impl VariantData {
160 pub(crate) fn get_field_type_ref(&self, field_name: &Name) -> Option<&TypeRef> { 114 pub(crate) fn get_field_type_ref(&self, field_name: &Name) -> Option<&TypeRef> {
161 self.fields() 115 self.fields()
162 .iter() 116 .iter()
163 .find(|f| f.name == *field_name) 117 .find(|f| f.name() == field_name)
164 .map(|f| &f.type_ref) 118 .map(|f| f.type_ref())
165 }
166
167 pub fn fields(&self) -> &[StructField] {
168 match *self {
169 VariantData::Struct(ref fields) | VariantData::Tuple(ref fields) => fields,
170 _ => &[],
171 }
172 }
173 pub fn is_struct(&self) -> bool {
174 match self {
175 VariantData::Struct(..) => true,
176 _ => false,
177 }
178 }
179 pub fn is_tuple(&self) -> bool {
180 match self {
181 VariantData::Tuple(..) => true,
182 _ => false,
183 }
184 }
185 pub fn is_unit(&self) -> bool {
186 match self {
187 VariantData::Unit => true,
188 _ => false,
189 }
190 } 119 }
191} 120}