aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2018-12-25 12:31:30 +0000
committerFlorian Diebold <[email protected]>2018-12-25 14:16:42 +0000
commit07a72859650254d8ba326e2c9683ae52164cb3b5 (patch)
treebc652bf0deb9f0d12380081b04585a2beaa97fce /crates/ra_hir
parent4cb7b0f2af9787abe1c73fc3922e9b426a96e0ef (diff)
Collect field data for structs/enum variants
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/adt.rs69
-rw-r--r--crates/ra_hir/src/function.rs3
-rw-r--r--crates/ra_hir/src/lib.rs6
-rw-r--r--crates/ra_hir/src/query_definitions.rs10
-rw-r--r--crates/ra_hir/src/ty.rs11
5 files changed, 87 insertions, 12 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index ee270ac45..b44f59f0b 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -1,10 +1,11 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{SmolStr, ast::{self, NameOwner}}; 3use ra_syntax::{SmolStr, ast::{self, NameOwner, StructFlavor}};
4 4
5use crate::{ 5use crate::{
6 DefId, Cancelable, 6 DefId, Cancelable,
7 db::{HirDatabase}, 7 db::{HirDatabase},
8 module::Module,
8 ty::{Ty}, 9 ty::{Ty},
9}; 10};
10 11
@@ -37,14 +38,18 @@ pub struct StructData {
37} 38}
38 39
39impl StructData { 40impl StructData {
40 pub(crate) fn new(struct_def: ast::StructDef) -> StructData { 41 pub(crate) fn new(
42 db: &impl HirDatabase,
43 module: &Module,
44 struct_def: ast::StructDef,
45 ) -> Cancelable<StructData> {
41 let name = struct_def 46 let name = struct_def
42 .name() 47 .name()
43 .map(|n| n.text()) 48 .map(|n| n.text())
44 .unwrap_or(SmolStr::new("[error]")); 49 .unwrap_or(SmolStr::new("[error]"));
45 let variant_data = VariantData::Unit; // TODO implement this 50 let variant_data = VariantData::new(db, module, struct_def.flavor())?;
46 let variant_data = Arc::new(variant_data); 51 let variant_data = Arc::new(variant_data);
47 StructData { name, variant_data } 52 Ok(StructData { name, variant_data })
48 } 53 }
49 54
50 pub fn name(&self) -> &SmolStr { 55 pub fn name(&self) -> &SmolStr {
@@ -81,13 +86,30 @@ pub struct EnumData {
81} 86}
82 87
83impl EnumData { 88impl EnumData {
84 pub(crate) fn new(enum_def: ast::EnumDef) -> Self { 89 pub(crate) fn new(
90 db: &impl HirDatabase,
91 module: &Module,
92 enum_def: ast::EnumDef,
93 ) -> Cancelable<Self> {
85 let name = enum_def 94 let name = enum_def
86 .name() 95 .name()
87 .map(|n| n.text()) 96 .map(|n| n.text())
88 .unwrap_or(SmolStr::new("[error]")); 97 .unwrap_or(SmolStr::new("[error]"));
89 let variants = Vec::new(); // TODO implement this 98 let variants = if let Some(evl) = enum_def.variant_list() {
90 EnumData { name, variants } 99 evl.variants()
100 .map(|v| {
101 Ok((
102 v.name()
103 .map(|n| n.text())
104 .unwrap_or_else(|| SmolStr::new("[error]")),
105 Arc::new(VariantData::new(db, module, v.flavor())?),
106 ))
107 })
108 .collect::<Cancelable<_>>()?
109 } else {
110 Vec::new()
111 };
112 Ok(EnumData { name, variants })
91 } 113 }
92} 114}
93 115
@@ -107,6 +129,39 @@ pub enum VariantData {
107} 129}
108 130
109impl VariantData { 131impl VariantData {
132 pub fn new(db: &impl HirDatabase, module: &Module, flavor: StructFlavor) -> Cancelable<Self> {
133 Ok(match flavor {
134 StructFlavor::Tuple(fl) => {
135 let fields = fl
136 .fields()
137 .enumerate()
138 .map(|(i, fd)| {
139 Ok(StructField {
140 name: SmolStr::new(i.to_string()),
141 ty: Ty::new_opt(db, &module, fd.type_ref())?,
142 })
143 })
144 .collect::<Cancelable<_>>()?;
145 VariantData::Tuple(fields)
146 }
147 StructFlavor::Named(fl) => {
148 let fields = fl
149 .fields()
150 .map(|fd| {
151 Ok(StructField {
152 name: fd
153 .name()
154 .map(|n| n.text())
155 .unwrap_or_else(|| SmolStr::new("[error]")),
156 ty: Ty::new_opt(db, &module, fd.type_ref())?,
157 })
158 })
159 .collect::<Cancelable<_>>()?;
160 VariantData::Struct(fields)
161 }
162 StructFlavor::Unit => VariantData::Unit,
163 })
164 }
110 pub fn fields(&self) -> &[StructField] { 165 pub fn fields(&self) -> &[StructField] {
111 match *self { 166 match *self {
112 VariantData::Struct(ref fields) | VariantData::Tuple(ref fields) => fields, 167 VariantData::Struct(ref fields) | VariantData::Tuple(ref fields) => fields,
diff --git a/crates/ra_hir/src/function.rs b/crates/ra_hir/src/function.rs
index d36477b48..01f0f3a66 100644
--- a/crates/ra_hir/src/function.rs
+++ b/crates/ra_hir/src/function.rs
@@ -46,8 +46,7 @@ impl Function {
46 } 46 }
47 47
48 pub fn module(&self, db: &impl HirDatabase) -> Cancelable<Module> { 48 pub fn module(&self, db: &impl HirDatabase) -> Cancelable<Module> {
49 let loc = self.fn_id.0.loc(db); 49 self.fn_id.0.module(db)
50 Module::new(db, loc.source_root_id, loc.module_id)
51 } 50 }
52} 51}
53 52
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 81526fe9c..796970d8a 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -135,6 +135,12 @@ impl DefId {
135 }; 135 };
136 Ok(res) 136 Ok(res)
137 } 137 }
138
139 /// For a module, returns that module; for any other def, returns the containing module.
140 pub fn module(self, db: &impl HirDatabase) -> Cancelable<Module> {
141 let loc = self.loc(db);
142 Module::new(db, loc.source_root_id, loc.module_id)
143 }
138} 144}
139 145
140/// Identifier of item within a specific file. This is stable over reparses, so 146/// Identifier of item within a specific file. This is stable over reparses, so
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs
index 72440d1d6..405e359f1 100644
--- a/crates/ra_hir/src/query_definitions.rs
+++ b/crates/ra_hir/src/query_definitions.rs
@@ -52,7 +52,12 @@ pub(super) fn struct_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ar
52 let syntax = db.file_item(def_loc.source_item_id); 52 let syntax = db.file_item(def_loc.source_item_id);
53 let struct_def = 53 let struct_def =
54 ast::StructDef::cast(syntax.borrowed()).expect("struct def should point to StructDef node"); 54 ast::StructDef::cast(syntax.borrowed()).expect("struct def should point to StructDef node");
55 Ok(Arc::new(StructData::new(struct_def.borrowed()))) 55 let module = def_id.module(db)?;
56 Ok(Arc::new(StructData::new(
57 db,
58 &module,
59 struct_def.borrowed(),
60 )?))
56} 61}
57 62
58pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> { 63pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> {
@@ -61,7 +66,8 @@ pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<
61 let syntax = db.file_item(def_loc.source_item_id); 66 let syntax = db.file_item(def_loc.source_item_id);
62 let enum_def = 67 let enum_def =
63 ast::EnumDef::cast(syntax.borrowed()).expect("enum def should point to EnumDef node"); 68 ast::EnumDef::cast(syntax.borrowed()).expect("enum def should point to EnumDef node");
64 Ok(Arc::new(EnumData::new(enum_def.borrowed()))) 69 let module = def_id.module(db)?;
70 Ok(Arc::new(EnumData::new(db, &module, enum_def.borrowed())?))
65} 71}
66 72
67pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<SourceFileItems> { 73pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<SourceFileItems> {
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 386af8120..e2428a37f 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -156,6 +156,15 @@ impl Ty {
156 Ok(ty) 156 Ok(ty)
157 } 157 }
158 158
159 pub(crate) fn new_opt(
160 db: &impl HirDatabase,
161 module: &Module,
162 node: Option<ast::TypeRef>,
163 ) -> Cancelable<Self> {
164 node.map(|n| Ty::new(db, module, n))
165 .unwrap_or(Ok(Ty::Unknown))
166 }
167
159 pub(crate) fn new( 168 pub(crate) fn new(
160 db: &impl HirDatabase, 169 db: &impl HirDatabase,
161 module: &Module, 170 module: &Module,
@@ -534,7 +543,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
534 Ty::Unknown 543 Ty::Unknown
535 } 544 }
536 ast::Expr::StructLit(e) => { 545 ast::Expr::StructLit(e) => {
537 let (ty, variant_data) = self.resolve_variant(e.path())?; 546 let (ty, _variant_data) = self.resolve_variant(e.path())?;
538 if let Some(nfl) = e.named_field_list() { 547 if let Some(nfl) = e.named_field_list() {
539 for field in nfl.fields() { 548 for field in nfl.fields() {
540 if let Some(e) = field.expr() { 549 if let Some(e) = field.expr() {