diff options
author | Florian Diebold <[email protected]> | 2018-12-25 12:31:30 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2018-12-25 14:16:42 +0000 |
commit | 07a72859650254d8ba326e2c9683ae52164cb3b5 (patch) | |
tree | bc652bf0deb9f0d12380081b04585a2beaa97fce /crates/ra_hir/src | |
parent | 4cb7b0f2af9787abe1c73fc3922e9b426a96e0ef (diff) |
Collect field data for structs/enum variants
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 69 | ||||
-rw-r--r-- | crates/ra_hir/src/function.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/query_definitions.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 11 |
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 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SmolStr, ast::{self, NameOwner}}; | 3 | use ra_syntax::{SmolStr, ast::{self, NameOwner, StructFlavor}}; |
4 | 4 | ||
5 | use crate::{ | 5 | use 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 | ||
39 | impl StructData { | 40 | impl 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 | ||
83 | impl EnumData { | 88 | impl 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 | ||
109 | impl VariantData { | 131 | impl 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 | ||
58 | pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> { | 63 | pub(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 | ||
67 | pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<SourceFileItems> { | 73 | pub(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() { |