diff options
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 61193b4d8..be5d17d85 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -2,11 +2,12 @@ | |||
2 | //! representation. | 2 | //! representation. |
3 | 3 | ||
4 | use either::Either; | 4 | use either::Either; |
5 | |||
5 | use hir_expand::name::{name, AsName, Name}; | 6 | use hir_expand::name::{name, AsName, Name}; |
6 | use ra_arena::Arena; | 7 | use ra_arena::Arena; |
7 | use ra_syntax::{ | 8 | use ra_syntax::{ |
8 | ast::{ | 9 | ast::{ |
9 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, | 10 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, |
10 | TypeAscriptionOwner, | 11 | TypeAscriptionOwner, |
11 | }, | 12 | }, |
12 | AstNode, AstPtr, | 13 | AstNode, AstPtr, |
@@ -24,23 +25,28 @@ use crate::{ | |||
24 | path::GenericArgs, | 25 | path::GenericArgs, |
25 | path::Path, | 26 | path::Path, |
26 | type_ref::{Mutability, TypeRef}, | 27 | type_ref::{Mutability, TypeRef}, |
28 | ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc, | ||
29 | StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, | ||
27 | }; | 30 | }; |
28 | 31 | ||
29 | pub(super) fn lower( | 32 | pub(super) fn lower( |
30 | db: &impl DefDatabase, | 33 | db: &impl DefDatabase, |
34 | def: DefWithBodyId, | ||
31 | expander: Expander, | 35 | expander: Expander, |
32 | params: Option<ast::ParamList>, | 36 | params: Option<ast::ParamList>, |
33 | body: Option<ast::Expr>, | 37 | body: Option<ast::Expr>, |
34 | ) -> (Body, BodySourceMap) { | 38 | ) -> (Body, BodySourceMap) { |
35 | ExprCollector { | 39 | ExprCollector { |
36 | expander, | ||
37 | db, | 40 | db, |
41 | def, | ||
42 | expander, | ||
38 | source_map: BodySourceMap::default(), | 43 | source_map: BodySourceMap::default(), |
39 | body: Body { | 44 | body: Body { |
40 | exprs: Arena::default(), | 45 | exprs: Arena::default(), |
41 | pats: Arena::default(), | 46 | pats: Arena::default(), |
42 | params: Vec::new(), | 47 | params: Vec::new(), |
43 | body_expr: ExprId::dummy(), | 48 | body_expr: ExprId::dummy(), |
49 | defs: Vec::new(), | ||
44 | }, | 50 | }, |
45 | } | 51 | } |
46 | .collect(params, body) | 52 | .collect(params, body) |
@@ -48,6 +54,7 @@ pub(super) fn lower( | |||
48 | 54 | ||
49 | struct ExprCollector<DB> { | 55 | struct ExprCollector<DB> { |
50 | db: DB, | 56 | db: DB, |
57 | def: DefWithBodyId, | ||
51 | expander: Expander, | 58 | expander: Expander, |
52 | 59 | ||
53 | body: Body, | 60 | body: Body, |
@@ -365,8 +372,9 @@ where | |||
365 | arg_types.push(type_ref); | 372 | arg_types.push(type_ref); |
366 | } | 373 | } |
367 | } | 374 | } |
375 | let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); | ||
368 | let body = self.collect_expr_opt(e.body()); | 376 | let body = self.collect_expr_opt(e.body()); |
369 | self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) | 377 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
370 | } | 378 | } |
371 | ast::Expr::BinExpr(e) => { | 379 | ast::Expr::BinExpr(e) => { |
372 | let lhs = self.collect_expr_opt(e.lhs()); | 380 | let lhs = self.collect_expr_opt(e.lhs()); |
@@ -466,6 +474,7 @@ where | |||
466 | Some(block) => block, | 474 | Some(block) => block, |
467 | None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), | 475 | None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), |
468 | }; | 476 | }; |
477 | self.collect_block_items(&block); | ||
469 | let statements = block | 478 | let statements = block |
470 | .statements() | 479 | .statements() |
471 | .map(|s| match s { | 480 | .map(|s| match s { |
@@ -482,6 +491,51 @@ where | |||
482 | self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) | 491 | self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) |
483 | } | 492 | } |
484 | 493 | ||
494 | fn collect_block_items(&mut self, block: &ast::Block) { | ||
495 | let container = ContainerId::DefWithBodyId(self.def); | ||
496 | for item in block.items() { | ||
497 | let def: ModuleDefId = match item { | ||
498 | ast::ModuleItem::FnDef(def) => { | ||
499 | let ast_id = self.expander.ast_id(&def); | ||
500 | FunctionLoc { container: container.into(), ast_id }.intern(self.db).into() | ||
501 | } | ||
502 | ast::ModuleItem::TypeAliasDef(def) => { | ||
503 | let ast_id = self.expander.ast_id(&def); | ||
504 | TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into() | ||
505 | } | ||
506 | ast::ModuleItem::ConstDef(def) => { | ||
507 | let ast_id = self.expander.ast_id(&def); | ||
508 | ConstLoc { container: container.into(), ast_id }.intern(self.db).into() | ||
509 | } | ||
510 | ast::ModuleItem::StaticDef(def) => { | ||
511 | let ast_id = self.expander.ast_id(&def); | ||
512 | StaticLoc { container, ast_id }.intern(self.db).into() | ||
513 | } | ||
514 | ast::ModuleItem::StructDef(def) => { | ||
515 | let ast_id = self.expander.ast_id(&def); | ||
516 | StructLoc { container, ast_id }.intern(self.db).into() | ||
517 | } | ||
518 | ast::ModuleItem::EnumDef(def) => { | ||
519 | let ast_id = self.expander.ast_id(&def); | ||
520 | EnumLoc { container, ast_id }.intern(self.db).into() | ||
521 | } | ||
522 | ast::ModuleItem::UnionDef(def) => { | ||
523 | let ast_id = self.expander.ast_id(&def); | ||
524 | UnionLoc { container, ast_id }.intern(self.db).into() | ||
525 | } | ||
526 | ast::ModuleItem::TraitDef(def) => { | ||
527 | let ast_id = self.expander.ast_id(&def); | ||
528 | TraitLoc { container, ast_id }.intern(self.db).into() | ||
529 | } | ||
530 | ast::ModuleItem::ImplBlock(_) | ||
531 | | ast::ModuleItem::UseItem(_) | ||
532 | | ast::ModuleItem::ExternCrateItem(_) | ||
533 | | ast::ModuleItem::Module(_) => continue, | ||
534 | }; | ||
535 | self.body.defs.push(def) | ||
536 | } | ||
537 | } | ||
538 | |||
485 | fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { | 539 | fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { |
486 | if let Some(block) = expr { | 540 | if let Some(block) = expr { |
487 | self.collect_block(block) | 541 | self.collect_block(block) |