diff options
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 84 |
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; | |||
6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
7 | use ra_syntax::{ | 7 | use 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 | ||
12 | use crate::{ | 12 | use 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)] |
29 | pub struct Body { | 29 | pub 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 | ||
466 | struct ExprCollector { | 465 | pub(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 | ||
475 | impl ExprCollector { | 474 | impl 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 | ||
918 | pub(crate) fn body_with_source_map_query( | 920 | pub(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 | ||
931 | pub(crate) fn body_hir_query(db: &impl HirDatabase, func: Function) -> Arc<Body> { | 936 | pub(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)] | ||
936 | fn 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 | } |