diff options
Diffstat (limited to 'crates/ra_hir/src/adt.rs')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 75 |
1 files changed, 26 insertions, 49 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index e0f515642..dc936e826 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use ra_arena::{RawId, Arena, impl_arena_id}; | ||
6 | use ra_syntax::{ | 7 | use ra_syntax::{ |
7 | TreeArc, | 8 | TreeArc, |
8 | ast::{self, NameOwner, StructFlavor} | 9 | ast::{self, NameOwner, StructFlavor} |
@@ -12,7 +13,6 @@ use crate::{ | |||
12 | Name, AsName, Struct, Enum, EnumVariant, Crate, | 13 | Name, AsName, Struct, Enum, EnumVariant, Crate, |
13 | HirDatabase, HirFileId, | 14 | HirDatabase, HirFileId, |
14 | type_ref::TypeRef, | 15 | type_ref::TypeRef, |
15 | ids::LocationCtx, | ||
16 | }; | 16 | }; |
17 | 17 | ||
18 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 18 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
@@ -66,43 +66,47 @@ fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> | |||
66 | } | 66 | } |
67 | 67 | ||
68 | impl EnumVariant { | 68 | impl EnumVariant { |
69 | pub fn source_impl(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) { | 69 | pub(crate) fn source_impl( |
70 | &self, | ||
71 | db: &impl HirDatabase, | ||
72 | ) -> (HirFileId, TreeArc<ast::EnumVariant>) { | ||
70 | let (file_id, enum_def) = self.parent.source(db); | 73 | let (file_id, enum_def) = self.parent.source(db); |
71 | let var = variants(&*enum_def) | 74 | let var = variants(&*enum_def) |
72 | .nth(self.idx as usize) | 75 | .zip(db.enum_data(self.parent).variants.iter()) |
76 | .find(|(_syntax, (id, _))| *id == self.id) | ||
73 | .unwrap() | 77 | .unwrap() |
78 | .0 | ||
74 | .to_owned(); | 79 | .to_owned(); |
75 | (file_id, var) | 80 | (file_id, var) |
76 | } | 81 | } |
77 | } | 82 | } |
78 | 83 | ||
84 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
85 | pub(crate) struct EnumVariantId(RawId); | ||
86 | impl_arena_id!(EnumVariantId); | ||
87 | |||
79 | #[derive(Debug, Clone, PartialEq, Eq)] | 88 | #[derive(Debug, Clone, PartialEq, Eq)] |
80 | pub struct EnumData { | 89 | pub struct EnumData { |
81 | pub(crate) name: Option<Name>, | 90 | pub(crate) name: Option<Name>, |
82 | pub(crate) variants: Vec<(Name, EnumVariant)>, | 91 | pub(crate) variants: Arena<EnumVariantId, EnumVariantData>, |
83 | } | 92 | } |
84 | 93 | ||
85 | impl EnumData { | 94 | impl EnumData { |
86 | fn new(enum_def: &ast::EnumDef, variants: Vec<(Name, EnumVariant)>) -> Self { | ||
87 | let name = enum_def.name().map(|n| n.as_name()); | ||
88 | EnumData { name, variants } | ||
89 | } | ||
90 | |||
91 | pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> { | 95 | pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> { |
92 | let (_file_id, enum_def) = e.source(db); | 96 | let (_file_id, enum_def) = e.source(db); |
93 | let variants = variants(&*enum_def) | 97 | let mut res = EnumData { |
94 | .enumerate() | 98 | name: enum_def.name().map(|n| n.as_name()), |
95 | .filter_map(|(idx, variant_def)| { | 99 | variants: Arena::default(), |
96 | let name = variant_def.name()?.as_name(); | 100 | }; |
97 | let var = EnumVariant { | 101 | for var in variants(&*enum_def) { |
98 | parent: e, | 102 | let data = EnumVariantData { |
99 | idx: idx as u32, | 103 | name: var.name().map(|it| it.as_name()), |
100 | }; | 104 | variant_data: Arc::new(VariantData::new(var.flavor())), |
101 | Some((name, var)) | 105 | }; |
102 | }) | 106 | res.variants.alloc(data); |
103 | .collect(); | 107 | } |
104 | 108 | ||
105 | Arc::new(EnumData::new(&*enum_def, variants)) | 109 | Arc::new(res) |
106 | } | 110 | } |
107 | } | 111 | } |
108 | 112 | ||
@@ -110,33 +114,6 @@ impl EnumData { | |||
110 | pub struct EnumVariantData { | 114 | pub struct EnumVariantData { |
111 | pub(crate) name: Option<Name>, | 115 | pub(crate) name: Option<Name>, |
112 | pub(crate) variant_data: Arc<VariantData>, | 116 | pub(crate) variant_data: Arc<VariantData>, |
113 | pub(crate) parent_enum: Enum, | ||
114 | } | ||
115 | |||
116 | impl EnumVariantData { | ||
117 | fn new(variant_def: &ast::EnumVariant, parent_enum: Enum) -> EnumVariantData { | ||
118 | let name = variant_def.name().map(|n| n.as_name()); | ||
119 | let variant_data = VariantData::new(variant_def.flavor()); | ||
120 | let variant_data = Arc::new(variant_data); | ||
121 | EnumVariantData { | ||
122 | name, | ||
123 | variant_data, | ||
124 | parent_enum, | ||
125 | } | ||
126 | } | ||
127 | |||
128 | pub(crate) fn enum_variant_data_query( | ||
129 | db: &impl HirDatabase, | ||
130 | var: EnumVariant, | ||
131 | ) -> Arc<EnumVariantData> { | ||
132 | let (file_id, variant_def) = var.source(db); | ||
133 | let enum_def = variant_def.parent_enum(); | ||
134 | let ctx = LocationCtx::new(db, var.module(db), file_id); | ||
135 | let e = Enum { | ||
136 | id: ctx.to_def(enum_def), | ||
137 | }; | ||
138 | Arc::new(EnumVariantData::new(&*variant_def, e)) | ||
139 | } | ||
140 | } | 117 | } |
141 | 118 | ||
142 | /// A single field of an enum variant or struct | 119 | /// A single field of an enum variant or struct |