diff options
Diffstat (limited to 'crates/ra_hir_def/src/item_tree')
-rw-r--r-- | crates/ra_hir_def/src/item_tree/lower.rs | 51 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/tests.rs | 2 |
2 files changed, 43 insertions, 10 deletions
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs index f2b8a9418..42af8bb5e 100644 --- a/crates/ra_hir_def/src/item_tree/lower.rs +++ b/crates/ra_hir_def/src/item_tree/lower.rs | |||
@@ -36,6 +36,7 @@ pub(super) struct Ctx { | |||
36 | source_ast_id_map: Arc<AstIdMap>, | 36 | source_ast_id_map: Arc<AstIdMap>, |
37 | body_ctx: crate::body::LowerCtx, | 37 | body_ctx: crate::body::LowerCtx, |
38 | inner_items: Vec<ModItem>, | 38 | inner_items: Vec<ModItem>, |
39 | forced_visibility: Option<RawVisibility>, | ||
39 | } | 40 | } |
40 | 41 | ||
41 | impl Ctx { | 42 | impl Ctx { |
@@ -47,6 +48,7 @@ impl Ctx { | |||
47 | source_ast_id_map: db.ast_id_map(file), | 48 | source_ast_id_map: db.ast_id_map(file), |
48 | body_ctx: crate::body::LowerCtx::new(db, file), | 49 | body_ctx: crate::body::LowerCtx::new(db, file), |
49 | inner_items: Vec::new(), | 50 | inner_items: Vec::new(), |
51 | forced_visibility: None, | ||
50 | } | 52 | } |
51 | } | 53 | } |
52 | 54 | ||
@@ -117,6 +119,7 @@ impl Ctx { | |||
117 | } | 119 | } |
118 | 120 | ||
119 | fn collect_inner_items(&mut self, container: &SyntaxNode) { | 121 | fn collect_inner_items(&mut self, container: &SyntaxNode) { |
122 | let forced_vis = self.forced_visibility.take(); | ||
120 | let mut inner_items = mem::replace(&mut self.tree.inner_items, FxHashMap::default()); | 123 | let mut inner_items = mem::replace(&mut self.tree.inner_items, FxHashMap::default()); |
121 | inner_items.extend( | 124 | inner_items.extend( |
122 | container.descendants().skip(1).filter_map(ast::ModuleItem::cast).filter_map(|item| { | 125 | container.descendants().skip(1).filter_map(ast::ModuleItem::cast).filter_map(|item| { |
@@ -125,6 +128,7 @@ impl Ctx { | |||
125 | }), | 128 | }), |
126 | ); | 129 | ); |
127 | self.tree.inner_items = inner_items; | 130 | self.tree.inner_items = inner_items; |
131 | self.forced_visibility = forced_vis; | ||
128 | } | 132 | } |
129 | 133 | ||
130 | fn lower_assoc_item(&mut self, item: &ast::ModuleItem) -> Option<AssocItem> { | 134 | fn lower_assoc_item(&mut self, item: &ast::ModuleItem) -> Option<AssocItem> { |
@@ -304,6 +308,7 @@ impl Ctx { | |||
304 | visibility, | 308 | visibility, |
305 | generic_params: GenericParams::default(), | 309 | generic_params: GenericParams::default(), |
306 | has_self_param, | 310 | has_self_param, |
311 | is_unsafe: func.unsafe_token().is_some(), | ||
307 | params, | 312 | params, |
308 | ret_type, | 313 | ret_type, |
309 | ast_id, | 314 | ast_id, |
@@ -320,9 +325,10 @@ impl Ctx { | |||
320 | let name = type_alias.name()?.as_name(); | 325 | let name = type_alias.name()?.as_name(); |
321 | let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it)); | 326 | let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it)); |
322 | let visibility = self.lower_visibility(type_alias); | 327 | let visibility = self.lower_visibility(type_alias); |
328 | let bounds = self.lower_type_bounds(type_alias); | ||
323 | let generic_params = self.lower_generic_params(GenericsOwner::TypeAlias, type_alias); | 329 | let generic_params = self.lower_generic_params(GenericsOwner::TypeAlias, type_alias); |
324 | let ast_id = self.source_ast_id_map.ast_id(type_alias); | 330 | let ast_id = self.source_ast_id_map.ast_id(type_alias); |
325 | let res = TypeAlias { name, visibility, generic_params, type_ref, ast_id }; | 331 | let res = TypeAlias { name, visibility, bounds, generic_params, type_ref, ast_id }; |
326 | Some(id(self.tree.type_aliases.alloc(res))) | 332 | Some(id(self.tree.type_aliases.alloc(res))) |
327 | } | 333 | } |
328 | 334 | ||
@@ -330,8 +336,9 @@ impl Ctx { | |||
330 | let name = static_.name()?.as_name(); | 336 | let name = static_.name()?.as_name(); |
331 | let type_ref = self.lower_type_ref_opt(static_.ascribed_type()); | 337 | let type_ref = self.lower_type_ref_opt(static_.ascribed_type()); |
332 | let visibility = self.lower_visibility(static_); | 338 | let visibility = self.lower_visibility(static_); |
339 | let mutable = static_.mut_token().is_some(); | ||
333 | let ast_id = self.source_ast_id_map.ast_id(static_); | 340 | let ast_id = self.source_ast_id_map.ast_id(static_); |
334 | let res = Static { name, visibility, type_ref, ast_id }; | 341 | let res = Static { name, visibility, mutable, type_ref, ast_id }; |
335 | Some(id(self.tree.statics.alloc(res))) | 342 | Some(id(self.tree.statics.alloc(res))) |
336 | } | 343 | } |
337 | 344 | ||
@@ -376,12 +383,14 @@ impl Ctx { | |||
376 | let generic_params = self.lower_generic_params(GenericsOwner::Trait(trait_def), trait_def); | 383 | let generic_params = self.lower_generic_params(GenericsOwner::Trait(trait_def), trait_def); |
377 | let auto = trait_def.auto_token().is_some(); | 384 | let auto = trait_def.auto_token().is_some(); |
378 | let items = trait_def.item_list().map(|list| { | 385 | let items = trait_def.item_list().map(|list| { |
379 | list.items() | 386 | self.with_inherited_visibility(visibility.clone(), |this| { |
380 | .flat_map(|item| { | 387 | list.items() |
381 | self.collect_inner_items(item.syntax()); | 388 | .flat_map(|item| { |
382 | self.lower_assoc_item(&item) | 389 | this.collect_inner_items(item.syntax()); |
383 | }) | 390 | this.lower_assoc_item(&item) |
384 | .collect() | 391 | }) |
392 | .collect() | ||
393 | }) | ||
385 | }); | 394 | }); |
386 | let ast_id = self.source_ast_id_map.ast_id(trait_def); | 395 | let ast_id = self.source_ast_id_map.ast_id(trait_def); |
387 | let res = Trait { | 396 | let res = Trait { |
@@ -549,11 +558,23 @@ impl Ctx { | |||
549 | generics | 558 | generics |
550 | } | 559 | } |
551 | 560 | ||
561 | fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec<TypeBound> { | ||
562 | if let Some(bound_list) = node.type_bound_list() { | ||
563 | bound_list.bounds().map(|it| TypeBound::from_ast(&self.body_ctx, it)).collect() | ||
564 | } else { | ||
565 | Vec::new() | ||
566 | } | ||
567 | } | ||
568 | |||
552 | fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { | 569 | fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { |
553 | Attrs::new(item, &self.hygiene) | 570 | Attrs::new(item, &self.hygiene) |
554 | } | 571 | } |
555 | fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility { | 572 | fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility { |
556 | RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene) | 573 | if let Some(vis) = self.forced_visibility.as_ref() { |
574 | vis.clone() | ||
575 | } else { | ||
576 | RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene) | ||
577 | } | ||
557 | } | 578 | } |
558 | fn lower_type_ref(&self, type_ref: &ast::TypeRef) -> TypeRef { | 579 | fn lower_type_ref(&self, type_ref: &ast::TypeRef) -> TypeRef { |
559 | TypeRef::from_ast(&self.body_ctx, type_ref.clone()) | 580 | TypeRef::from_ast(&self.body_ctx, type_ref.clone()) |
@@ -562,6 +583,18 @@ impl Ctx { | |||
562 | TypeRef::from_ast_opt(&self.body_ctx, type_ref) | 583 | TypeRef::from_ast_opt(&self.body_ctx, type_ref) |
563 | } | 584 | } |
564 | 585 | ||
586 | /// Forces the visibility `vis` to be used for all items lowered during execution of `f`. | ||
587 | fn with_inherited_visibility<R>( | ||
588 | &mut self, | ||
589 | vis: RawVisibility, | ||
590 | f: impl FnOnce(&mut Self) -> R, | ||
591 | ) -> R { | ||
592 | let old = mem::replace(&mut self.forced_visibility, Some(vis)); | ||
593 | let res = f(self); | ||
594 | self.forced_visibility = old; | ||
595 | res | ||
596 | } | ||
597 | |||
565 | fn next_field_idx(&self) -> Idx<Field> { | 598 | fn next_field_idx(&self) -> Idx<Field> { |
566 | Idx::from_raw(RawId::from(self.tree.fields.len() as u32)) | 599 | Idx::from_raw(RawId::from(self.tree.fields.len() as u32)) |
567 | } | 600 | } |
diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs index b60e6cbb0..1db1ce7a9 100644 --- a/crates/ra_hir_def/src/item_tree/tests.rs +++ b/crates/ra_hir_def/src/item_tree/tests.rs | |||
@@ -204,7 +204,7 @@ Impl { generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_ | |||
204 | 204 | ||
205 | inner items: | 205 | inner items: |
206 | FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): | 206 | FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): |
207 | - Function { name: Name(Text("end")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("W"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("W"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Write"))] }, generic_args: [None] }) }] }, has_self_param: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | 207 | - Function { name: Name(Text("end")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("W"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("W"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Write"))] }, generic_args: [None] }) }] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } |
208 | "###); | 208 | "###); |
209 | } | 209 | } |
210 | 210 | ||