diff options
-rw-r--r-- | crates/ra_hir/src/adt.rs | 75 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/mock.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 9 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_path.rs | 10 | ||||
-rw-r--r-- | crates/ra_ide_api/src/db.rs | 1 |
7 files changed, 55 insertions, 74 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 |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 4fc47aba5..249a4aba9 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -11,7 +11,7 @@ use crate::{ | |||
11 | db::HirDatabase, | 11 | db::HirDatabase, |
12 | expr::BodySyntaxMapping, | 12 | expr::BodySyntaxMapping, |
13 | ty::{InferenceResult, VariantDef}, | 13 | ty::{InferenceResult, VariantDef}, |
14 | adt::VariantData, | 14 | adt::{VariantData, EnumVariantId}, |
15 | generics::GenericParams, | 15 | generics::GenericParams, |
16 | docs::{Documentation, Docs, docs_from_ast}, | 16 | docs::{Documentation, Docs, docs_from_ast}, |
17 | module_tree::ModuleId, | 17 | module_tree::ModuleId, |
@@ -252,8 +252,20 @@ impl Enum { | |||
252 | db.enum_data(*self).name.clone() | 252 | db.enum_data(*self).name.clone() |
253 | } | 253 | } |
254 | 254 | ||
255 | pub fn variants(&self, db: &impl HirDatabase) -> Vec<(Name, EnumVariant)> { | 255 | pub fn variants(&self, db: &impl HirDatabase) -> Vec<EnumVariant> { |
256 | db.enum_data(*self).variants.clone() | 256 | db.enum_data(*self) |
257 | .variants | ||
258 | .iter() | ||
259 | .map(|(id, _)| EnumVariant { parent: *self, id }) | ||
260 | .collect() | ||
261 | } | ||
262 | |||
263 | pub fn variant(&self, db: &impl HirDatabase, name: &Name) -> Option<EnumVariant> { | ||
264 | db.enum_data(*self) | ||
265 | .variants | ||
266 | .iter() | ||
267 | .find(|(_id, data)| data.name.as_ref() == Some(name)) | ||
268 | .map(|(id, _)| EnumVariant { parent: *self, id }) | ||
257 | } | 269 | } |
258 | 270 | ||
259 | pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { | 271 | pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { |
@@ -270,7 +282,7 @@ impl Docs for Enum { | |||
270 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 282 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
271 | pub struct EnumVariant { | 283 | pub struct EnumVariant { |
272 | pub(crate) parent: Enum, | 284 | pub(crate) parent: Enum, |
273 | pub(crate) idx: u32, | 285 | pub(crate) id: EnumVariantId, |
274 | } | 286 | } |
275 | 287 | ||
276 | impl EnumVariant { | 288 | impl EnumVariant { |
@@ -285,11 +297,13 @@ impl EnumVariant { | |||
285 | } | 297 | } |
286 | 298 | ||
287 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { | 299 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { |
288 | db.enum_variant_data(*self).name.clone() | 300 | db.enum_data(self.parent).variants[self.id].name.clone() |
289 | } | 301 | } |
290 | 302 | ||
291 | pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { | 303 | pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { |
292 | db.enum_variant_data(*self).variant_data.clone() | 304 | db.enum_data(self.parent).variants[self.id] |
305 | .variant_data | ||
306 | .clone() | ||
293 | } | 307 | } |
294 | 308 | ||
295 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> { | 309 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> { |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 5304f5d31..5a29e54d6 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -8,12 +8,12 @@ use crate::{ | |||
8 | SourceFileItems, SourceItemId, Crate, Module, HirInterner, | 8 | SourceFileItems, SourceItemId, Crate, Module, HirInterner, |
9 | query_definitions, | 9 | query_definitions, |
10 | Function, FnSignature, FnScopes, | 10 | Function, FnSignature, FnScopes, |
11 | Struct, Enum, EnumVariant, | 11 | Struct, Enum, |
12 | macros::MacroExpansion, | 12 | macros::MacroExpansion, |
13 | module_tree::ModuleTree, | 13 | module_tree::ModuleTree, |
14 | nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, | 14 | nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, |
15 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, VariantDef}, | 15 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, VariantDef}, |
16 | adt::{StructData, EnumData, EnumVariantData}, | 16 | adt::{StructData, EnumData}, |
17 | impl_block::ModuleImplBlocks, | 17 | impl_block::ModuleImplBlocks, |
18 | generics::{GenericParams, GenericDef}, | 18 | generics::{GenericParams, GenericDef}, |
19 | }; | 19 | }; |
@@ -35,9 +35,6 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> { | |||
35 | #[salsa::invoke(crate::adt::EnumData::enum_data_query)] | 35 | #[salsa::invoke(crate::adt::EnumData::enum_data_query)] |
36 | fn enum_data(&self, e: Enum) -> Arc<EnumData>; | 36 | fn enum_data(&self, e: Enum) -> Arc<EnumData>; |
37 | 37 | ||
38 | #[salsa::invoke(crate::adt::EnumVariantData::enum_variant_data_query)] | ||
39 | fn enum_variant_data(&self, var: EnumVariant) -> Arc<EnumVariantData>; | ||
40 | |||
41 | #[salsa::invoke(crate::ty::infer)] | 38 | #[salsa::invoke(crate::ty::infer)] |
42 | fn infer(&self, func: Function) -> Arc<InferenceResult>; | 39 | fn infer(&self, func: Function) -> Arc<InferenceResult>; |
43 | 40 | ||
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 361366f6a..1a83a5c87 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -231,7 +231,6 @@ salsa::database_storage! { | |||
231 | fn type_for_field() for db::TypeForFieldQuery; | 231 | fn type_for_field() for db::TypeForFieldQuery; |
232 | fn struct_data() for db::StructDataQuery; | 232 | fn struct_data() for db::StructDataQuery; |
233 | fn enum_data() for db::EnumDataQuery; | 233 | fn enum_data() for db::EnumDataQuery; |
234 | fn enum_variant_data() for db::EnumVariantDataQuery; | ||
235 | fn impls_in_module() for db::ImplsInModuleQuery; | 234 | fn impls_in_module() for db::ImplsInModuleQuery; |
236 | fn impls_in_crate() for db::ImplsInCrateQuery; | 235 | fn impls_in_crate() for db::ImplsInCrateQuery; |
237 | fn body_hir() for db::BodyHirQuery; | 236 | fn body_hir() for db::BodyHirQuery; |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 639726b5e..028c1882f 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -397,13 +397,8 @@ impl ItemMap { | |||
397 | ModuleDef::Enum(e) => { | 397 | ModuleDef::Enum(e) => { |
398 | // enum variant | 398 | // enum variant |
399 | tested_by!(item_map_enum_importing); | 399 | tested_by!(item_map_enum_importing); |
400 | let matching_variant = e | 400 | match e.variant(db, &segment.name) { |
401 | .variants(db) | 401 | Some(variant) => PerNs::both(variant.into(), (*e).into()), |
402 | .into_iter() | ||
403 | .find(|(n, _variant)| n == &segment.name); | ||
404 | |||
405 | match matching_variant { | ||
406 | Some((_n, variant)) => PerNs::both(variant.into(), (*e).into()), | ||
407 | None => PerNs::none(), | 402 | None => PerNs::none(), |
408 | } | 403 | } |
409 | } | 404 | } |
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index e72586e2e..e3f1d42f8 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -27,18 +27,18 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
27 | } | 27 | } |
28 | } | 28 | } |
29 | hir::ModuleDef::Enum(e) => { | 29 | hir::ModuleDef::Enum(e) => { |
30 | e.variants(ctx.db) | 30 | e.variants(ctx.db).into_iter().for_each(|variant| { |
31 | .into_iter() | 31 | if let Some(name) = variant.name(ctx.db) { |
32 | .for_each(|(variant_name, variant)| { | ||
33 | CompletionItem::new( | 32 | CompletionItem::new( |
34 | CompletionKind::Reference, | 33 | CompletionKind::Reference, |
35 | ctx.source_range(), | 34 | ctx.source_range(), |
36 | variant_name.to_string(), | 35 | name.to_string(), |
37 | ) | 36 | ) |
38 | .kind(CompletionItemKind::EnumVariant) | 37 | .kind(CompletionItemKind::EnumVariant) |
39 | .set_documentation(variant.docs(ctx.db)) | 38 | .set_documentation(variant.docs(ctx.db)) |
40 | .add_to(acc) | 39 | .add_to(acc) |
41 | }); | 40 | } |
41 | }); | ||
42 | } | 42 | } |
43 | _ => return, | 43 | _ => return, |
44 | }; | 44 | }; |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index bff6b7237..11305613c 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -104,7 +104,6 @@ salsa::database_storage! { | |||
104 | fn type_for_field() for hir::db::TypeForFieldQuery; | 104 | fn type_for_field() for hir::db::TypeForFieldQuery; |
105 | fn struct_data() for hir::db::StructDataQuery; | 105 | fn struct_data() for hir::db::StructDataQuery; |
106 | fn enum_data() for hir::db::EnumDataQuery; | 106 | fn enum_data() for hir::db::EnumDataQuery; |
107 | fn enum_variant_data() for hir::db::EnumVariantDataQuery; | ||
108 | fn impls_in_module() for hir::db::ImplsInModuleQuery; | 107 | fn impls_in_module() for hir::db::ImplsInModuleQuery; |
109 | fn impls_in_crate() for hir::db::ImplsInCrateQuery; | 108 | fn impls_in_crate() for hir::db::ImplsInCrateQuery; |
110 | fn body_hir() for hir::db::BodyHirQuery; | 109 | fn body_hir() for hir::db::BodyHirQuery; |