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.rs80
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;
4use rustc_hash::FxHashMap; 4use rustc_hash::FxHashMap;
5 5
6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
7use ra_db::{LocalSyntaxPtr, Cancelable}; 7use ra_db::LocalSyntaxPtr;
8use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}; 8use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor};
9 9
10use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; 10use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName};
11use 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)]
13pub struct ExprId(RawId); 14pub 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)]
108pub 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)]
107pub enum Expr { 118pub 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
191pub use ra_syntax::ast::PrefixOp as UnaryOp; 203pub 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
346pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<Body>> { 359pub(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
350struct ExprCollector { 363struct 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
779pub(crate) fn body_syntax_mapping( 832pub(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}