diff options
author | Benjamin Coenen <[email protected]> | 2020-04-08 17:12:15 +0100 |
---|---|---|
committer | Benjamin Coenen <[email protected]> | 2020-04-08 17:12:15 +0100 |
commit | 8f1dba6f9ae1d8d314dd9d007e4c582ed1403e8d (patch) | |
tree | e6d269d0a10de37aff7c5f2c2849eab9a9108b02 /crates/ra_hir_def/src | |
parent | 18a5e164838e1dc2abcc6b79d4fc2f96ffd2507c (diff) |
feat: add attributes support on struct fields and method #3870
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 25 |
2 files changed, 24 insertions, 31 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 8527a6cad..7fc4cd76e 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -4,19 +4,17 @@ use std::sync::Arc; | |||
4 | 4 | ||
5 | use either::Either; | 5 | use either::Either; |
6 | use hir_expand::{ | 6 | use hir_expand::{ |
7 | hygiene::Hygiene, | ||
8 | name::{AsName, Name}, | 7 | name::{AsName, Name}, |
9 | InFile, | 8 | InFile, |
10 | }; | 9 | }; |
11 | use ra_arena::{map::ArenaMap, Arena}; | 10 | use ra_arena::{map::ArenaMap, Arena}; |
12 | use ra_cfg::CfgOptions; | ||
13 | use ra_prof::profile; | 11 | use ra_prof::profile; |
14 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; | 12 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; |
15 | 13 | ||
16 | use crate::{ | 14 | use crate::{ |
17 | attr::Attrs, db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, | 15 | db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef, |
18 | type_ref::TypeRef, visibility::RawVisibility, EnumId, LocalEnumVariantId, LocalStructFieldId, | 16 | visibility::RawVisibility, EnumId, LocalEnumVariantId, LocalStructFieldId, Lookup, StructId, |
19 | Lookup, StructId, UnionId, VariantId, | 17 | UnionId, VariantId, |
20 | }; | 18 | }; |
21 | 19 | ||
22 | /// Note that we use `StructData` for unions as well! | 20 | /// Note that we use `StructData` for unions as well! |
@@ -51,8 +49,6 @@ pub struct StructFieldData { | |||
51 | pub name: Name, | 49 | pub name: Name, |
52 | pub type_ref: TypeRef, | 50 | pub type_ref: TypeRef, |
53 | pub visibility: RawVisibility, | 51 | pub visibility: RawVisibility, |
54 | pub attrs: Attrs, | ||
55 | // TODO: add attributes | ||
56 | } | 52 | } |
57 | 53 | ||
58 | impl StructData { | 54 | impl StructData { |
@@ -186,10 +182,6 @@ pub enum StructKind { | |||
186 | Unit, | 182 | Unit, |
187 | } | 183 | } |
188 | 184 | ||
189 | fn is_cfg_enabled(cfg_options: &CfgOptions, attrs: &Attrs) -> bool { | ||
190 | attrs.by_key("cfg").tt_values().all(|tt| cfg_options.is_cfg_enabled(tt) != Some(false)) | ||
191 | } | ||
192 | |||
193 | fn lower_struct( | 185 | fn lower_struct( |
194 | db: &dyn DefDatabase, | 186 | db: &dyn DefDatabase, |
195 | trace: &mut Trace<StructFieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>, | 187 | trace: &mut Trace<StructFieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>, |
@@ -198,21 +190,12 @@ fn lower_struct( | |||
198 | match &ast.value { | 190 | match &ast.value { |
199 | ast::StructKind::Tuple(fl) => { | 191 | ast::StructKind::Tuple(fl) => { |
200 | for (i, fd) in fl.fields().enumerate() { | 192 | for (i, fd) in fl.fields().enumerate() { |
201 | let attrs = Attrs::new(&fd, &Hygiene::new(db.upcast(), ast.file_id)); | ||
202 | |||
203 | // Need verification about parent cfg_options and current with current attributes | ||
204 | // If it is we are in a case where the cfg is not enabled then we don't have to add this field to check | ||
205 | // if !is_cfg_enabled(&crate_graph[module_id.krate].cfg_options, &attrs) { | ||
206 | // continue; | ||
207 | // } | ||
208 | |||
209 | trace.alloc( | 193 | trace.alloc( |
210 | || Either::Left(fd.clone()), | 194 | || Either::Left(fd.clone()), |
211 | || StructFieldData { | 195 | || StructFieldData { |
212 | name: Name::new_tuple_field(i), | 196 | name: Name::new_tuple_field(i), |
213 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), | 197 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), |
214 | visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), | 198 | visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), |
215 | attrs: Attrs::new(&fd, &Hygiene::new(db.upcast(), ast.file_id)), | ||
216 | }, | 199 | }, |
217 | ); | 200 | ); |
218 | } | 201 | } |
@@ -220,19 +203,12 @@ fn lower_struct( | |||
220 | } | 203 | } |
221 | ast::StructKind::Record(fl) => { | 204 | ast::StructKind::Record(fl) => { |
222 | for fd in fl.fields() { | 205 | for fd in fl.fields() { |
223 | let attrs = Attrs::new(&fd, &Hygiene::new(db.upcast(), ast.file_id)); | ||
224 | // Need verification about parent cfg_options and current with current attributes | ||
225 | // If it is we are in a case where the cfg is not enabled then we don't have to add this field to check | ||
226 | // if !is_cfg_enabled(&crate_graph[module_id.krate].cfg_options, &attrs) { | ||
227 | // continue; | ||
228 | // } | ||
229 | trace.alloc( | 206 | trace.alloc( |
230 | || Either::Right(fd.clone()), | 207 | || Either::Right(fd.clone()), |
231 | || StructFieldData { | 208 | || StructFieldData { |
232 | name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), | 209 | name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), |
233 | type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), | 210 | type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), |
234 | visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), | 211 | visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), |
235 | attrs: Attrs::new(&fd, &Hygiene::new(db.upcast(), ast.file_id)), | ||
236 | }, | 212 | }, |
237 | ); | 213 | ); |
238 | } | 214 | } |
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 934c3b94e..606ec48b0 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -7,6 +7,7 @@ use hir_expand::{ | |||
7 | name::{name, AsName, Name}, | 7 | name::{name, AsName, Name}, |
8 | AstId, InFile, | 8 | AstId, InFile, |
9 | }; | 9 | }; |
10 | use ra_cfg::CfgOptions; | ||
10 | use ra_prof::profile; | 11 | use ra_prof::profile; |
11 | use ra_syntax::ast::{ | 12 | use ra_syntax::ast::{ |
12 | self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner, | 13 | self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner, |
@@ -67,6 +68,7 @@ impl FunctionData { | |||
67 | } | 68 | } |
68 | } | 69 | } |
69 | let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); | 70 | let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); |
71 | |||
70 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { | 72 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { |
71 | TypeRef::from_ast(type_ref) | 73 | TypeRef::from_ast(type_ref) |
72 | } else { | 74 | } else { |
@@ -215,6 +217,7 @@ impl ImplData { | |||
215 | let module_id = impl_loc.container.module(db); | 217 | let module_id = impl_loc.container.module(db); |
216 | 218 | ||
217 | let mut items = Vec::new(); | 219 | let mut items = Vec::new(); |
220 | |||
218 | if let Some(item_list) = src.value.item_list() { | 221 | if let Some(item_list) = src.value.item_list() { |
219 | items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id)); | 222 | items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id)); |
220 | items.extend(collect_impl_items_in_macros( | 223 | items.extend(collect_impl_items_in_macros( |
@@ -315,6 +318,10 @@ fn collect_impl_items_in_macro( | |||
315 | } | 318 | } |
316 | } | 319 | } |
317 | 320 | ||
321 | fn is_cfg_enabled(cfg_options: &CfgOptions, attrs: &Attrs) -> bool { | ||
322 | attrs.by_key("cfg").tt_values().all(|tt| cfg_options.is_cfg_enabled(tt) != Some(false)) | ||
323 | } | ||
324 | |||
318 | fn collect_impl_items( | 325 | fn collect_impl_items( |
319 | db: &dyn DefDatabase, | 326 | db: &dyn DefDatabase, |
320 | impl_items: impl Iterator<Item = ImplItem>, | 327 | impl_items: impl Iterator<Item = ImplItem>, |
@@ -322,16 +329,26 @@ fn collect_impl_items( | |||
322 | id: ImplId, | 329 | id: ImplId, |
323 | ) -> Vec<AssocItemId> { | 330 | ) -> Vec<AssocItemId> { |
324 | let items = db.ast_id_map(file_id); | 331 | let items = db.ast_id_map(file_id); |
332 | let crate_graph = db.crate_graph(); | ||
333 | let module_id = id.lookup(db).container.module(db); | ||
325 | 334 | ||
326 | impl_items | 335 | impl_items |
327 | .map(|item_node| match item_node { | 336 | .filter_map(|item_node| match item_node { |
328 | ast::ImplItem::FnDef(it) => { | 337 | ast::ImplItem::FnDef(it) => { |
329 | let def = FunctionLoc { | 338 | let def = FunctionLoc { |
330 | container: AssocContainerId::ImplId(id), | 339 | container: AssocContainerId::ImplId(id), |
331 | ast_id: AstId::new(file_id, items.ast_id(&it)), | 340 | ast_id: AstId::new(file_id, items.ast_id(&it)), |
332 | } | 341 | } |
333 | .intern(db); | 342 | .intern(db); |
334 | def.into() | 343 | |
344 | if !is_cfg_enabled( | ||
345 | &crate_graph[module_id.krate].cfg_options, | ||
346 | &db.function_data(def).attrs, | ||
347 | ) { | ||
348 | None | ||
349 | } else { | ||
350 | Some(def.into()) | ||
351 | } | ||
335 | } | 352 | } |
336 | ast::ImplItem::ConstDef(it) => { | 353 | ast::ImplItem::ConstDef(it) => { |
337 | let def = ConstLoc { | 354 | let def = ConstLoc { |
@@ -339,7 +356,7 @@ fn collect_impl_items( | |||
339 | ast_id: AstId::new(file_id, items.ast_id(&it)), | 356 | ast_id: AstId::new(file_id, items.ast_id(&it)), |
340 | } | 357 | } |
341 | .intern(db); | 358 | .intern(db); |
342 | def.into() | 359 | Some(def.into()) |
343 | } | 360 | } |
344 | ast::ImplItem::TypeAliasDef(it) => { | 361 | ast::ImplItem::TypeAliasDef(it) => { |
345 | let def = TypeAliasLoc { | 362 | let def = TypeAliasLoc { |
@@ -347,7 +364,7 @@ fn collect_impl_items( | |||
347 | ast_id: AstId::new(file_id, items.ast_id(&it)), | 364 | ast_id: AstId::new(file_id, items.ast_id(&it)), |
348 | } | 365 | } |
349 | .intern(db); | 366 | .intern(db); |
350 | def.into() | 367 | Some(def.into()) |
351 | } | 368 | } |
352 | }) | 369 | }) |
353 | .collect() | 370 | .collect() |