aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r--crates/ra_hir/src/expr.rs84
1 files changed, 41 insertions, 43 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index a85422955..b2a237ece 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -6,11 +6,11 @@ use rustc_hash::FxHashMap;
6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
7use ra_syntax::{ 7use ra_syntax::{
8 SyntaxNodePtr, AstPtr, AstNode, 8 SyntaxNodePtr, AstPtr, AstNode,
9 ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor, TypeAscriptionOwner} 9 ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind, TypeAscriptionOwner}
10}; 10};
11 11
12use crate::{ 12use crate::{
13 Path, Name, HirDatabase, Function, Resolver, 13 Path, Name, HirDatabase, Resolver,DefWithBody,
14 name::AsName, 14 name::AsName,
15 type_ref::{Mutability, TypeRef}, 15 type_ref::{Mutability, TypeRef},
16}; 16};
@@ -27,9 +27,8 @@ impl_arena_id!(ExprId);
27/// The body of an item (function, const etc.). 27/// The body of an item (function, const etc.).
28#[derive(Debug, Eq, PartialEq)] 28#[derive(Debug, Eq, PartialEq)]
29pub struct Body { 29pub struct Body {
30 // FIXME: this should be more general, consts & statics also have bodies 30 /// The def of the item this body belongs to
31 /// The Function of the item this body belongs to 31 owner: DefWithBody,
32 owner: Function,
33 exprs: Arena<ExprId, Expr>, 32 exprs: Arena<ExprId, Expr>,
34 pats: Arena<PatId, Pat>, 33 pats: Arena<PatId, Pat>,
35 /// The patterns for the function's parameters. While the parameter types are 34 /// The patterns for the function's parameters. While the parameter types are
@@ -66,7 +65,7 @@ impl Body {
66 self.body_expr 65 self.body_expr
67 } 66 }
68 67
69 pub fn owner(&self) -> Function { 68 pub fn owner(&self) -> DefWithBody {
70 self.owner 69 self.owner
71 } 70 }
72 71
@@ -463,8 +462,8 @@ impl Pat {
463 462
464// Queries 463// Queries
465 464
466struct ExprCollector { 465pub(crate) struct ExprCollector {
467 owner: Function, 466 owner: DefWithBody,
468 exprs: Arena<ExprId, Expr>, 467 exprs: Arena<ExprId, Expr>,
469 pats: Arena<PatId, Pat>, 468 pats: Arena<PatId, Pat>,
470 source_map: BodySourceMap, 469 source_map: BodySourceMap,
@@ -473,7 +472,7 @@ struct ExprCollector {
473} 472}
474 473
475impl ExprCollector { 474impl ExprCollector {
476 fn new(owner: Function) -> Self { 475 fn new(owner: DefWithBody) -> Self {
477 ExprCollector { 476 ExprCollector {
478 owner, 477 owner,
479 exprs: Arena::default(), 478 exprs: Arena::default(),
@@ -516,8 +515,8 @@ impl ExprCollector {
516 let else_branch = e 515 let else_branch = e
517 .else_branch() 516 .else_branch()
518 .map(|b| match b { 517 .map(|b| match b {
519 ast::ElseBranchFlavor::Block(it) => self.collect_block(it), 518 ast::ElseBranch::Block(it) => self.collect_block(it),
520 ast::ElseBranchFlavor::IfExpr(elif) => { 519 ast::ElseBranch::IfExpr(elif) => {
521 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); 520 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap();
522 self.collect_expr(expr) 521 self.collect_expr(expr)
523 } 522 }
@@ -533,8 +532,8 @@ impl ExprCollector {
533 let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr())); 532 let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr()));
534 let then_branch = self.collect_block_opt(e.then_branch()); 533 let then_branch = self.collect_block_opt(e.then_branch());
535 let else_branch = e.else_branch().map(|b| match b { 534 let else_branch = e.else_branch().map(|b| match b {
536 ast::ElseBranchFlavor::Block(it) => self.collect_block(it), 535 ast::ElseBranch::Block(it) => self.collect_block(it),
537 ast::ElseBranchFlavor::IfExpr(elif) => { 536 ast::ElseBranch::IfExpr(elif) => {
538 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); 537 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap();
539 self.collect_expr(expr) 538 self.collect_expr(expr)
540 } 539 }
@@ -726,14 +725,8 @@ impl ExprCollector {
726 self.alloc_expr(Expr::Array { exprs }, syntax_ptr) 725 self.alloc_expr(Expr::Array { exprs }, syntax_ptr)
727 } 726 }
728 ast::ExprKind::Literal(e) => { 727 ast::ExprKind::Literal(e) => {
729 let child = if let Some(child) = e.literal_expr() { 728 let lit = match e.kind() {
730 child 729 LiteralKind::IntNumber { suffix } => {
731 } else {
732 return self.alloc_expr(Expr::Missing, syntax_ptr);
733 };
734
735 let lit = match child.flavor() {
736 LiteralFlavor::IntNumber { suffix } => {
737 let known_name = suffix 730 let known_name = suffix
738 .and_then(|it| IntTy::from_suffix(&it).map(UncertainIntTy::Known)); 731 .and_then(|it| IntTy::from_suffix(&it).map(UncertainIntTy::Known));
739 732
@@ -742,7 +735,7 @@ impl ExprCollector {
742 known_name.unwrap_or(UncertainIntTy::Unknown), 735 known_name.unwrap_or(UncertainIntTy::Unknown),
743 ) 736 )
744 } 737 }
745 LiteralFlavor::FloatNumber { suffix } => { 738 LiteralKind::FloatNumber { suffix } => {
746 let known_name = suffix 739 let known_name = suffix
747 .and_then(|it| FloatTy::from_suffix(&it).map(UncertainFloatTy::Known)); 740 .and_then(|it| FloatTy::from_suffix(&it).map(UncertainFloatTy::Known));
748 741
@@ -751,13 +744,13 @@ impl ExprCollector {
751 known_name.unwrap_or(UncertainFloatTy::Unknown), 744 known_name.unwrap_or(UncertainFloatTy::Unknown),
752 ) 745 )
753 } 746 }
754 LiteralFlavor::ByteString => Literal::ByteString(Default::default()), 747 LiteralKind::ByteString => Literal::ByteString(Default::default()),
755 LiteralFlavor::String => Literal::String(Default::default()), 748 LiteralKind::String => Literal::String(Default::default()),
756 LiteralFlavor::Byte => { 749 LiteralKind::Byte => {
757 Literal::Int(Default::default(), UncertainIntTy::Known(IntTy::u8())) 750 Literal::Int(Default::default(), UncertainIntTy::Known(IntTy::u8()))
758 } 751 }
759 LiteralFlavor::Bool => Literal::Bool(Default::default()), 752 LiteralKind::Bool => Literal::Bool(Default::default()),
760 LiteralFlavor::Char => Literal::Char(Default::default()), 753 LiteralKind::Char => Literal::Char(Default::default()),
761 }; 754 };
762 self.alloc_expr(Expr::Literal(lit), syntax_ptr) 755 self.alloc_expr(Expr::Literal(lit), syntax_ptr)
763 } 756 }
@@ -766,6 +759,7 @@ impl ExprCollector {
766 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 759 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
767 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 760 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
768 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 761 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
762 ast::ExprKind::MacroCall(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
769 } 763 }
770 } 764 }
771 765
@@ -871,12 +865,20 @@ impl ExprCollector {
871 } 865 }
872 } 866 }
873 867
868 fn collect_const_body(&mut self, node: &ast::ConstDef) {
869 let body = self.collect_expr_opt(node.body());
870 self.body_expr = Some(body);
871 }
872
873 fn collect_static_body(&mut self, node: &ast::StaticDef) {
874 let body = self.collect_expr_opt(node.body());
875 self.body_expr = Some(body);
876 }
877
874 fn collect_fn_body(&mut self, node: &ast::FnDef) { 878 fn collect_fn_body(&mut self, node: &ast::FnDef) {
875 if let Some(param_list) = node.param_list() { 879 if let Some(param_list) = node.param_list() {
876 if let Some(self_param) = param_list.self_param() { 880 if let Some(self_param) = param_list.self_param() {
877 let self_param = SyntaxNodePtr::new( 881 let self_param = SyntaxNodePtr::new(self_param.syntax());
878 self_param.self_kw().expect("self param without self keyword").syntax(),
879 );
880 let param_pat = self.alloc_pat( 882 let param_pat = self.alloc_pat(
881 Pat::Bind { 883 Pat::Bind {
882 name: Name::self_param(), 884 name: Name::self_param(),
@@ -917,24 +919,20 @@ impl ExprCollector {
917 919
918pub(crate) fn body_with_source_map_query( 920pub(crate) fn body_with_source_map_query(
919 db: &impl HirDatabase, 921 db: &impl HirDatabase,
920 func: Function, 922 def: DefWithBody,
921) -> (Arc<Body>, Arc<BodySourceMap>) { 923) -> (Arc<Body>, Arc<BodySourceMap>) {
922 let mut collector = ExprCollector::new(func); 924 let mut collector = ExprCollector::new(def);
923 925
924 // FIXME: consts, etc. 926 match def {
925 collector.collect_fn_body(&func.source(db).1); 927 DefWithBody::Const(ref c) => collector.collect_const_body(&c.source(db).1),
928 DefWithBody::Function(ref f) => collector.collect_fn_body(&f.source(db).1),
929 DefWithBody::Static(ref s) => collector.collect_static_body(&s.source(db).1),
930 }
926 931
927 let (body, source_map) = collector.finish(); 932 let (body, source_map) = collector.finish();
928 (Arc::new(body), Arc::new(source_map)) 933 (Arc::new(body), Arc::new(source_map))
929} 934}
930 935
931pub(crate) fn body_hir_query(db: &impl HirDatabase, func: Function) -> Arc<Body> { 936pub(crate) fn body_hir_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<Body> {
932 db.body_with_source_map(func).0 937 db.body_with_source_map(def).0
933}
934
935#[cfg(test)]
936fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> (Body, BodySourceMap) {
937 let mut collector = ExprCollector::new(function);
938 collector.collect_fn_body(node);
939 collector.finish()
940} 938}