diff options
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 80 |
1 files changed, 65 insertions, 15 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index f0936e9f3..663338844 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -4,10 +4,11 @@ use std::sync::Arc; | |||
4 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
5 | 5 | ||
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_db::{LocalSyntaxPtr, Cancelable}; | 7 | use ra_db::LocalSyntaxPtr; |
8 | use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}; | 8 | use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}; |
9 | 9 | ||
10 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; | 10 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; |
11 | use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; | ||
11 | 12 | ||
12 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 13 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
13 | pub struct ExprId(RawId); | 14 | pub struct ExprId(RawId); |
@@ -104,6 +105,16 @@ impl BodySyntaxMapping { | |||
104 | } | 105 | } |
105 | 106 | ||
106 | #[derive(Debug, Clone, Eq, PartialEq)] | 107 | #[derive(Debug, Clone, Eq, PartialEq)] |
108 | pub enum Literal { | ||
109 | String(String), | ||
110 | ByteString(Vec<u8>), | ||
111 | Char(char), | ||
112 | Bool(bool), | ||
113 | Int(u64, UncertainIntTy), | ||
114 | Float(u64, UncertainFloatTy), // FIXME: f64 is not Eq | ||
115 | } | ||
116 | |||
117 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
107 | pub enum Expr { | 118 | pub enum Expr { |
108 | /// This is produced if syntax tree does not have a required expression piece. | 119 | /// This is produced if syntax tree does not have a required expression piece. |
109 | Missing, | 120 | Missing, |
@@ -171,7 +182,7 @@ pub enum Expr { | |||
171 | }, | 182 | }, |
172 | UnaryOp { | 183 | UnaryOp { |
173 | expr: ExprId, | 184 | expr: ExprId, |
174 | op: Option<UnaryOp>, | 185 | op: UnaryOp, |
175 | }, | 186 | }, |
176 | BinaryOp { | 187 | BinaryOp { |
177 | lhs: ExprId, | 188 | lhs: ExprId, |
@@ -186,6 +197,7 @@ pub enum Expr { | |||
186 | Tuple { | 197 | Tuple { |
187 | exprs: Vec<ExprId>, | 198 | exprs: Vec<ExprId>, |
188 | }, | 199 | }, |
200 | Literal(Literal), | ||
189 | } | 201 | } |
190 | 202 | ||
191 | pub use ra_syntax::ast::PrefixOp as UnaryOp; | 203 | pub use ra_syntax::ast::PrefixOp as UnaryOp; |
@@ -305,6 +317,7 @@ impl Expr { | |||
305 | f(*expr); | 317 | f(*expr); |
306 | } | 318 | } |
307 | } | 319 | } |
320 | Expr::Literal(_) => {} | ||
308 | } | 321 | } |
309 | } | 322 | } |
310 | } | 323 | } |
@@ -343,8 +356,8 @@ impl Pat { | |||
343 | 356 | ||
344 | // Queries | 357 | // Queries |
345 | 358 | ||
346 | pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<Body>> { | 359 | pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Arc<Body> { |
347 | Ok(Arc::clone(&body_syntax_mapping(db, def_id)?.body)) | 360 | Arc::clone(&body_syntax_mapping(db, def_id).body) |
348 | } | 361 | } |
349 | 362 | ||
350 | struct ExprCollector { | 363 | struct ExprCollector { |
@@ -599,8 +612,11 @@ impl ExprCollector { | |||
599 | } | 612 | } |
600 | ast::ExprKind::PrefixExpr(e) => { | 613 | ast::ExprKind::PrefixExpr(e) => { |
601 | let expr = self.collect_expr_opt(e.expr()); | 614 | let expr = self.collect_expr_opt(e.expr()); |
602 | let op = e.op(); | 615 | if let Some(op) = e.op() { |
603 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) | 616 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) |
617 | } else { | ||
618 | self.alloc_expr(Expr::Missing, syntax_ptr) | ||
619 | } | ||
604 | } | 620 | } |
605 | ast::ExprKind::LambdaExpr(e) => { | 621 | ast::ExprKind::LambdaExpr(e) => { |
606 | let mut args = Vec::new(); | 622 | let mut args = Vec::new(); |
@@ -633,13 +649,50 @@ impl ExprCollector { | |||
633 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 649 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); |
634 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 650 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
635 | } | 651 | } |
652 | ast::ExprKind::Literal(e) => { | ||
653 | let child = if let Some(child) = e.literal_expr() { | ||
654 | child | ||
655 | } else { | ||
656 | return self.alloc_expr(Expr::Missing, syntax_ptr); | ||
657 | }; | ||
658 | |||
659 | let lit = match child.flavor() { | ||
660 | LiteralFlavor::IntNumber { suffix } => { | ||
661 | let known_name = suffix | ||
662 | .map(|s| Name::new(s)) | ||
663 | .and_then(|name| UncertainIntTy::from_name(&name)); | ||
664 | |||
665 | Literal::Int( | ||
666 | Default::default(), | ||
667 | known_name.unwrap_or(UncertainIntTy::Unknown), | ||
668 | ) | ||
669 | } | ||
670 | LiteralFlavor::FloatNumber { suffix } => { | ||
671 | let known_name = suffix | ||
672 | .map(|s| Name::new(s)) | ||
673 | .and_then(|name| UncertainFloatTy::from_name(&name)); | ||
674 | |||
675 | Literal::Float( | ||
676 | Default::default(), | ||
677 | known_name.unwrap_or(UncertainFloatTy::Unknown), | ||
678 | ) | ||
679 | } | ||
680 | LiteralFlavor::ByteString => Literal::ByteString(Default::default()), | ||
681 | LiteralFlavor::String => Literal::String(Default::default()), | ||
682 | LiteralFlavor::Byte => { | ||
683 | Literal::Int(Default::default(), UncertainIntTy::Unsigned(UintTy::U8)) | ||
684 | } | ||
685 | LiteralFlavor::Bool => Literal::Bool(Default::default()), | ||
686 | LiteralFlavor::Char => Literal::Char(Default::default()), | ||
687 | }; | ||
688 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) | ||
689 | } | ||
636 | 690 | ||
637 | // TODO implement HIR for these: | 691 | // TODO implement HIR for these: |
638 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 692 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
639 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 693 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
640 | ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 694 | ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
641 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 695 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
642 | ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
643 | } | 696 | } |
644 | } | 697 | } |
645 | 698 | ||
@@ -776,17 +829,14 @@ pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping { | |||
776 | collector.into_body_syntax_mapping(params, body) | 829 | collector.into_body_syntax_mapping(params, body) |
777 | } | 830 | } |
778 | 831 | ||
779 | pub(crate) fn body_syntax_mapping( | 832 | pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, def_id: DefId) -> Arc<BodySyntaxMapping> { |
780 | db: &impl HirDatabase, | 833 | let def = def_id.resolve(db); |
781 | def_id: DefId, | ||
782 | ) -> Cancelable<Arc<BodySyntaxMapping>> { | ||
783 | let def = def_id.resolve(db)?; | ||
784 | 834 | ||
785 | let body_syntax_mapping = match def { | 835 | let body_syntax_mapping = match def { |
786 | Def::Function(f) => collect_fn_body_syntax(&f.source(db)?.1), | 836 | Def::Function(f) => collect_fn_body_syntax(&f.source(db).1), |
787 | // TODO: consts, etc. | 837 | // TODO: consts, etc. |
788 | _ => panic!("Trying to get body for item type without body"), | 838 | _ => panic!("Trying to get body for item type without body"), |
789 | }; | 839 | }; |
790 | 840 | ||
791 | Ok(Arc::new(body_syntax_mapping)) | 841 | Arc::new(body_syntax_mapping) |
792 | } | 842 | } |