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.rs75
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
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use ra_arena::{RawId, Arena, impl_arena_id};
6use ra_syntax::{ 7use 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
68impl EnumVariant { 68impl 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)]
85pub(crate) struct EnumVariantId(RawId);
86impl_arena_id!(EnumVariantId);
87
79#[derive(Debug, Clone, PartialEq, Eq)] 88#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct EnumData { 89pub 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
85impl EnumData { 94impl 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 {
110pub struct EnumVariantData { 114pub 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
116impl 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