aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs108
1 files changed, 91 insertions, 17 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 331736cb2..5323af097 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -1,14 +1,13 @@
1//! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` 1//! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr`
2//! representation. 2//! representation.
3 3
4use hir_expand::{ 4use either::Either;
5 either::Either, 5
6 name::{self, AsName, Name}, 6use hir_expand::name::{name, AsName, Name};
7};
8use ra_arena::Arena; 7use ra_arena::Arena;
9use ra_syntax::{ 8use ra_syntax::{
10 ast::{ 9 ast::{
11 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, 10 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner,
12 TypeAscriptionOwner, 11 TypeAscriptionOwner,
13 }, 12 },
14 AstNode, AstPtr, 13 AstNode, AstPtr,
@@ -26,23 +25,28 @@ use crate::{
26 path::GenericArgs, 25 path::GenericArgs,
27 path::Path, 26 path::Path,
28 type_ref::{Mutability, TypeRef}, 27 type_ref::{Mutability, TypeRef},
28 ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc,
29 StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
29}; 30};
30 31
31pub(super) fn lower( 32pub(super) fn lower(
32 db: &impl DefDatabase, 33 db: &impl DefDatabase,
34 def: DefWithBodyId,
33 expander: Expander, 35 expander: Expander,
34 params: Option<ast::ParamList>, 36 params: Option<ast::ParamList>,
35 body: Option<ast::Expr>, 37 body: Option<ast::Expr>,
36) -> (Body, BodySourceMap) { 38) -> (Body, BodySourceMap) {
37 ExprCollector { 39 ExprCollector {
38 expander,
39 db, 40 db,
41 def,
42 expander,
40 source_map: BodySourceMap::default(), 43 source_map: BodySourceMap::default(),
41 body: Body { 44 body: Body {
42 exprs: Arena::default(), 45 exprs: Arena::default(),
43 pats: Arena::default(), 46 pats: Arena::default(),
44 params: Vec::new(), 47 params: Vec::new(),
45 body_expr: ExprId::dummy(), 48 body_expr: ExprId::dummy(),
49 item_scope: Default::default(),
46 }, 50 },
47 } 51 }
48 .collect(params, body) 52 .collect(params, body)
@@ -50,6 +54,7 @@ pub(super) fn lower(
50 54
51struct ExprCollector<DB> { 55struct ExprCollector<DB> {
52 db: DB, 56 db: DB,
57 def: DefWithBodyId,
53 expander: Expander, 58 expander: Expander,
54 59
55 body: Body, 60 body: Body,
@@ -70,11 +75,11 @@ where
70 let ptr = AstPtr::new(&self_param); 75 let ptr = AstPtr::new(&self_param);
71 let param_pat = self.alloc_pat( 76 let param_pat = self.alloc_pat(
72 Pat::Bind { 77 Pat::Bind {
73 name: name::SELF_PARAM, 78 name: name![self],
74 mode: BindingAnnotation::Unannotated, 79 mode: BindingAnnotation::Unannotated,
75 subpat: None, 80 subpat: None,
76 }, 81 },
77 Either::B(ptr), 82 Either::Right(ptr),
78 ); 83 );
79 self.body.params.push(param_pat); 84 self.body.params.push(param_pat);
80 } 85 }
@@ -94,7 +99,7 @@ where
94 } 99 }
95 100
96 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { 101 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
97 let ptr = Either::A(ptr); 102 let ptr = Either::Left(ptr);
98 let id = self.body.exprs.alloc(expr); 103 let id = self.body.exprs.alloc(expr);
99 let src = self.expander.to_source(ptr); 104 let src = self.expander.to_source(ptr);
100 self.source_map.expr_map.insert(src, id); 105 self.source_map.expr_map.insert(src, id);
@@ -107,7 +112,7 @@ where
107 self.body.exprs.alloc(expr) 112 self.body.exprs.alloc(expr)
108 } 113 }
109 fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId { 114 fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId {
110 let ptr = Either::B(ptr); 115 let ptr = Either::Right(ptr);
111 let id = self.body.exprs.alloc(expr); 116 let id = self.body.exprs.alloc(expr);
112 let src = self.expander.to_source(ptr); 117 let src = self.expander.to_source(ptr);
113 self.source_map.expr_map.insert(src, id); 118 self.source_map.expr_map.insert(src, id);
@@ -277,7 +282,7 @@ where
277 ast::Expr::ParenExpr(e) => { 282 ast::Expr::ParenExpr(e) => {
278 let inner = self.collect_expr_opt(e.expr()); 283 let inner = self.collect_expr_opt(e.expr());
279 // make the paren expr point to the inner expression as well 284 // make the paren expr point to the inner expression as well
280 let src = self.expander.to_source(Either::A(syntax_ptr)); 285 let src = self.expander.to_source(Either::Left(syntax_ptr));
281 self.source_map.expr_map.insert(src, inner); 286 self.source_map.expr_map.insert(src, inner);
282 inner 287 inner
283 } 288 }
@@ -367,8 +372,9 @@ where
367 arg_types.push(type_ref); 372 arg_types.push(type_ref);
368 } 373 }
369 } 374 }
375 let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast);
370 let body = self.collect_expr_opt(e.body()); 376 let body = self.collect_expr_opt(e.body());
371 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)
372 } 378 }
373 ast::Expr::BinExpr(e) => { 379 ast::Expr::BinExpr(e) => {
374 let lhs = self.collect_expr_opt(e.lhs()); 380 let lhs = self.collect_expr_opt(e.lhs());
@@ -429,10 +435,17 @@ where
429 let index = self.collect_expr_opt(e.index()); 435 let index = self.collect_expr_opt(e.index());
430 self.alloc_expr(Expr::Index { base, index }, syntax_ptr) 436 self.alloc_expr(Expr::Index { base, index }, syntax_ptr)
431 } 437 }
432 438 ast::Expr::RangeExpr(e) => {
433 // FIXME implement HIR for these: 439 let lhs = e.start().map(|lhs| self.collect_expr(lhs));
434 ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 440 let rhs = e.end().map(|rhs| self.collect_expr(rhs));
435 ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 441 match e.op_kind() {
442 Some(range_type) => {
443 self.alloc_expr(Expr::Range { lhs, rhs, range_type }, syntax_ptr)
444 }
445 None => self.alloc_expr(Expr::Missing, syntax_ptr),
446 }
447 }
448 // FIXME expand to statements in statement position
436 ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { 449 ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) {
437 Some((mark, expansion)) => { 450 Some((mark, expansion)) => {
438 let id = self.collect_expr(expansion); 451 let id = self.collect_expr(expansion);
@@ -441,6 +454,9 @@ where
441 } 454 }
442 None => self.alloc_expr(Expr::Missing, syntax_ptr), 455 None => self.alloc_expr(Expr::Missing, syntax_ptr),
443 }, 456 },
457
458 // FIXME implement HIR for these:
459 ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
444 } 460 }
445 } 461 }
446 462
@@ -458,6 +474,7 @@ where
458 Some(block) => block, 474 Some(block) => block,
459 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), 475 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
460 }; 476 };
477 self.collect_block_items(&block);
461 let statements = block 478 let statements = block
462 .statements() 479 .statements()
463 .map(|s| match s { 480 .map(|s| match s {
@@ -474,6 +491,63 @@ where
474 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 491 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
475 } 492 }
476 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, name): (ModuleDefId, Option<ast::Name>) = match item {
498 ast::ModuleItem::FnDef(def) => {
499 let ast_id = self.expander.ast_id(&def);
500 (
501 FunctionLoc { container: container.into(), ast_id }.intern(self.db).into(),
502 def.name(),
503 )
504 }
505 ast::ModuleItem::TypeAliasDef(def) => {
506 let ast_id = self.expander.ast_id(&def);
507 (
508 TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into(),
509 def.name(),
510 )
511 }
512 ast::ModuleItem::ConstDef(def) => {
513 let ast_id = self.expander.ast_id(&def);
514 (
515 ConstLoc { container: container.into(), ast_id }.intern(self.db).into(),
516 def.name(),
517 )
518 }
519 ast::ModuleItem::StaticDef(def) => {
520 let ast_id = self.expander.ast_id(&def);
521 (StaticLoc { container, ast_id }.intern(self.db).into(), def.name())
522 }
523 ast::ModuleItem::StructDef(def) => {
524 let ast_id = self.expander.ast_id(&def);
525 (StructLoc { container, ast_id }.intern(self.db).into(), def.name())
526 }
527 ast::ModuleItem::EnumDef(def) => {
528 let ast_id = self.expander.ast_id(&def);
529 (EnumLoc { container, ast_id }.intern(self.db).into(), def.name())
530 }
531 ast::ModuleItem::UnionDef(def) => {
532 let ast_id = self.expander.ast_id(&def);
533 (UnionLoc { container, ast_id }.intern(self.db).into(), def.name())
534 }
535 ast::ModuleItem::TraitDef(def) => {
536 let ast_id = self.expander.ast_id(&def);
537 (TraitLoc { container, ast_id }.intern(self.db).into(), def.name())
538 }
539 ast::ModuleItem::ImplBlock(_)
540 | ast::ModuleItem::UseItem(_)
541 | ast::ModuleItem::ExternCrateItem(_)
542 | ast::ModuleItem::Module(_) => continue,
543 };
544 self.body.item_scope.define_def(def);
545 if let Some(name) = name {
546 self.body.item_scope.push_res(name.as_name(), def.into());
547 }
548 }
549 }
550
477 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { 551 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
478 if let Some(block) = expr { 552 if let Some(block) = expr {
479 self.collect_block(block) 553 self.collect_block(block)
@@ -541,7 +615,7 @@ where
541 ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing, 615 ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing,
542 }; 616 };
543 let ptr = AstPtr::new(&pat); 617 let ptr = AstPtr::new(&pat);
544 self.alloc_pat(pattern, Either::A(ptr)) 618 self.alloc_pat(pattern, Either::Left(ptr))
545 } 619 }
546 620
547 fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId { 621 fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId {