aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/adt.rs29
-rw-r--r--crates/ra_hir/src/code_model_api.rs2
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs18
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs15
4 files changed, 25 insertions, 39 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index f1b98cdd7..bcb705c24 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -7,13 +7,9 @@ use ra_syntax::{
7}; 7};
8 8
9use crate::{ 9use crate::{
10<<<<<<< HEAD
11 DefId, Name, AsName, Struct, Enum, HirDatabase, DefKind,
12=======
13 DefId, DefLoc, Name, AsName, Struct, Enum, EnumVariant, 10 DefId, DefLoc, Name, AsName, Struct, Enum, EnumVariant,
14 VariantData, StructField, HirDatabase, DefKind, 11 HirDatabase, DefKind,
15 SourceItemId, 12 SourceItemId,
16>>>>>>> 95ac72a3... Implement type inference for enum variants
17 type_ref::TypeRef, 13 type_ref::TypeRef,
18}; 14};
19 15
@@ -79,13 +75,11 @@ fn get_def_id(
79#[derive(Debug, Clone, PartialEq, Eq)] 75#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct EnumData { 76pub struct EnumData {
81 pub(crate) name: Option<Name>, 77 pub(crate) name: Option<Name>,
82 // TODO: keep track of names also since we already have them? 78 pub(crate) variants: Vec<(Name, EnumVariant)>,
83 // then we won't need additional db lookups
84 pub(crate) variants: Option<Vec<EnumVariant>>,
85} 79}
86 80
87impl EnumData { 81impl EnumData {
88 fn new(enum_def: &ast::EnumDef, variants: Option<Vec<EnumVariant>>) -> Self { 82 fn new(enum_def: &ast::EnumDef, variants: Vec<(Name, EnumVariant)>) -> Self {
89 let name = enum_def.name().map(|n| n.as_name()); 83 let name = enum_def.name().map(|n| n.as_name());
90 EnumData { name, variants } 84 EnumData { name, variants }
91 } 85 }
@@ -98,14 +92,21 @@ impl EnumData {
98 assert!(def_loc.kind == DefKind::Enum); 92 assert!(def_loc.kind == DefKind::Enum);
99 let syntax = db.file_item(def_loc.source_item_id); 93 let syntax = db.file_item(def_loc.source_item_id);
100 let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node"); 94 let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
101 let variants = enum_def.variant_list().map(|vl| { 95 let variants = if let Some(vl) = enum_def.variant_list() {
102 vl.variants() 96 vl.variants()
103 .map(|ev| { 97 .filter_map(|variant_def| {
104 let def_id = get_def_id(db, &def_loc, ev.syntax(), DefKind::EnumVariant); 98 let name = variant_def.name().map(|n| n.as_name());
105 EnumVariant::new(def_id) 99
100 name.map(|n| {
101 let def_id =
102 get_def_id(db, &def_loc, variant_def.syntax(), DefKind::EnumVariant);
103 (n, EnumVariant::new(def_id))
104 })
106 }) 105 })
107 .collect() 106 .collect()
108 }); 107 } else {
108 Vec::new()
109 };
109 Ok(Arc::new(EnumData::new(enum_def, variants))) 110 Ok(Arc::new(EnumData::new(enum_def, variants)))
110 } 111 }
111} 112}
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index c7d1bf0a6..725bc7d80 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -201,7 +201,7 @@ impl Enum {
201 Ok(db.enum_data(self.def_id)?.name.clone()) 201 Ok(db.enum_data(self.def_id)?.name.clone())
202 } 202 }
203 203
204 pub fn variants(&self, db: &impl HirDatabase) -> Cancelable<Option<Vec<EnumVariant>>> { 204 pub fn variants(&self, db: &impl HirDatabase) -> Cancelable<Vec<(Name, EnumVariant)>> {
205 Ok(db.enum_data(self.def_id)?.variants.clone()) 205 Ok(db.enum_data(self.def_id)?.variants.clone())
206 } 206 }
207} 207}
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index d7d62e863..878dc37c8 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -142,20 +142,10 @@ impl Module {
142 Def::Enum(e) => { 142 Def::Enum(e) => {
143 if segments.len() == idx + 1 { 143 if segments.len() == idx + 1 {
144 // enum variant 144 // enum variant
145 let matching_variant = e.variants(db)?.map(|variants| { 145 let matching_variant =
146 variants 146 e.variants(db)?.into_iter().find(|(n, _variant)| n == name);
147 .into_iter() 147
148 // FIXME: replace by match lol 148 if let Some((_n, variant)) = matching_variant {
149 .find(|variant| {
150 variant
151 .name(db)
152 .map(|o| o.map(|ref n| n == name))
153 .unwrap_or(Some(false))
154 .unwrap_or(false)
155 })
156 });
157
158 if let Some(Some(variant)) = matching_variant {
159 return Ok(PerNs::both(variant.def_id(), e.def_id())); 149 return Ok(PerNs::both(variant.def_id(), e.def_id()));
160 } else { 150 } else {
161 return Ok(PerNs::none()); 151 return Ok(PerNs::none());
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 6a55670d1..9bfec88d0 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -23,17 +23,12 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> C
23 } 23 }
24 hir::Def::Enum(e) => { 24 hir::Def::Enum(e) => {
25 e.variants(ctx.db)? 25 e.variants(ctx.db)?
26 .unwrap_or(vec![])
27 .into_iter() 26 .into_iter()
28 .for_each(|variant| { 27 .for_each(|(variant_name, _variant)| {
29 let variant_name = variant.name(ctx.db); 28 CompletionItem::new(CompletionKind::Reference, variant_name.to_string())
30 29 .kind(CompletionItemKind::EnumVariant)
31 if let Ok(Some(name)) = variant_name { 30 .add_to(acc)
32 CompletionItem::new(CompletionKind::Reference, name.to_string()) 31 });
33 .kind(CompletionItemKind::EnumVariant)
34 .add_to(acc)
35 }
36 })
37 } 32 }
38 _ => return Ok(()), 33 _ => return Ok(()),
39 }; 34 };