diff options
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 141 |
1 files changed, 53 insertions, 88 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 3f2689781..2f3432870 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -6,12 +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_db::{LocalSyntaxPtr, Cancelable}; | 7 | use ra_db::{LocalSyntaxPtr, Cancelable}; |
8 | use ra_syntax::{ | 8 | use ra_syntax::{ |
9 | SyntaxKind, | 9 | ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor} |
10 | ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner} | ||
11 | }; | 10 | }; |
12 | 11 | ||
13 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; | 12 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; |
14 | use crate::ty::primitive::{UintTy, IntTy, FloatTy, UncertainIntTy, UncertainFloatTy}; | 13 | use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; |
15 | 14 | ||
16 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
17 | pub struct ExprId(RawId); | 16 | pub struct ExprId(RawId); |
@@ -649,93 +648,59 @@ impl ExprCollector { | |||
649 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 648 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); |
650 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 649 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
651 | } | 650 | } |
652 | ast::ExprKind::LiteralExpr(e) => { | 651 | ast::ExprKind::Literal(e) => { |
653 | if let Some(child) = e.literal() { | 652 | let child = if let Some(child) = e.literal_expr() { |
654 | let c = child.syntax(); | 653 | child |
655 | let lit = match c.kind() { | 654 | } else { |
656 | SyntaxKind::INT_NUMBER => { | 655 | return self.alloc_expr(Expr::Missing, syntax_ptr); |
657 | let text = c.text().to_string(); | 656 | }; |
658 | 657 | let c = child.syntax(); | |
659 | // FIXME: don't do it like this. maybe use something like | 658 | |
660 | // the IntTy::from_name functions | 659 | let lit = match child.flavor() { |
661 | let ty = if text.ends_with("isize") { | 660 | LiteralFlavor::IntNumber { suffix } => { |
662 | UncertainIntTy::Signed(IntTy::Isize) | 661 | let known_name = suffix |
663 | } else if text.ends_with("i128") { | 662 | .map(|s| Name::new(s)) |
664 | UncertainIntTy::Signed(IntTy::I128) | 663 | .and_then(|name| UncertainIntTy::from_name(&name)); |
665 | } else if text.ends_with("i64") { | 664 | |
666 | UncertainIntTy::Signed(IntTy::I64) | 665 | if let Some(kn) = known_name { |
667 | } else if text.ends_with("i32") { | 666 | Literal::Int(0u64, kn) |
668 | UncertainIntTy::Signed(IntTy::I32) | 667 | } else { |
669 | } else if text.ends_with("i16") { | 668 | Literal::Int(0u64, UncertainIntTy::Unknown) |
670 | UncertainIntTy::Signed(IntTy::I16) | ||
671 | } else if text.ends_with("i8") { | ||
672 | UncertainIntTy::Signed(IntTy::I8) | ||
673 | } else if text.ends_with("usize") { | ||
674 | UncertainIntTy::Unsigned(UintTy::Usize) | ||
675 | } else if text.ends_with("u128") { | ||
676 | UncertainIntTy::Unsigned(UintTy::U128) | ||
677 | } else if text.ends_with("u64") { | ||
678 | UncertainIntTy::Unsigned(UintTy::U64) | ||
679 | } else if text.ends_with("u32") { | ||
680 | UncertainIntTy::Unsigned(UintTy::U32) | ||
681 | } else if text.ends_with("u16") { | ||
682 | UncertainIntTy::Unsigned(UintTy::U16) | ||
683 | } else if text.ends_with("u8") { | ||
684 | UncertainIntTy::Unsigned(UintTy::U8) | ||
685 | } else { | ||
686 | UncertainIntTy::Unknown | ||
687 | }; | ||
688 | |||
689 | // TODO: actually parse integer | ||
690 | Literal::Int(0u64, ty) | ||
691 | } | ||
692 | SyntaxKind::FLOAT_NUMBER => { | ||
693 | let text = c.text().to_string(); | ||
694 | |||
695 | // FIXME: don't do it like this. maybe use something like | ||
696 | // the IntTy::from_name functions | ||
697 | let ty = if text.ends_with("f64") { | ||
698 | UncertainFloatTy::Known(FloatTy::F64) | ||
699 | } else if text.ends_with("f32") { | ||
700 | UncertainFloatTy::Known(FloatTy::F32) | ||
701 | } else { | ||
702 | UncertainFloatTy::Unknown | ||
703 | }; | ||
704 | |||
705 | // TODO: actually parse value | ||
706 | Literal::Float(0, ty) | ||
707 | } | ||
708 | SyntaxKind::STRING => { | ||
709 | // FIXME: this likely includes the " characters | ||
710 | let text = c.text().to_string(); | ||
711 | Literal::String(text) | ||
712 | } | ||
713 | SyntaxKind::TRUE_KW => Literal::Bool(true), | ||
714 | SyntaxKind::FALSE_KW => Literal::Bool(false), | ||
715 | SyntaxKind::BYTE_STRING => { | ||
716 | // FIXME: this is completely incorrect for a variety | ||
717 | // of reasons, but at least it gives the right type | ||
718 | let bytes = c.text().to_string().into_bytes(); | ||
719 | Literal::ByteString(bytes) | ||
720 | } | ||
721 | SyntaxKind::CHAR => { | ||
722 | let character = c.text().char_at(1).unwrap_or('X'); | ||
723 | Literal::Char(character) | ||
724 | } | 669 | } |
725 | SyntaxKind::BYTE => { | 670 | } |
726 | let character = c.text().char_at(1).unwrap_or('X'); | 671 | LiteralFlavor::FloatNumber { suffix } => { |
727 | Literal::Int( | 672 | let known_name = suffix |
728 | character as u8 as u64, | 673 | .map(|s| Name::new(s)) |
729 | UncertainIntTy::Unsigned(UintTy::U8), | 674 | .and_then(|name| UncertainFloatTy::from_name(&name)); |
730 | ) | 675 | |
676 | if let Some(kn) = known_name { | ||
677 | Literal::Float(0u64, kn) | ||
678 | } else { | ||
679 | Literal::Float(0u64, UncertainFloatTy::Unknown) | ||
731 | } | 680 | } |
732 | _ => return self.alloc_expr(Expr::Missing, syntax_ptr), | 681 | } |
733 | }; | 682 | LiteralFlavor::ByteString => { |
734 | 683 | // FIXME: this is completely incorrect for a variety | |
735 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) | 684 | // of reasons, but at least it gives the right type |
736 | } else { | 685 | let bytes = c.text().to_string().into_bytes(); |
737 | self.alloc_expr(Expr::Missing, syntax_ptr) | 686 | Literal::ByteString(bytes) |
738 | } | 687 | } |
688 | LiteralFlavor::String => { | ||
689 | // FIXME: this likely includes the " characters | ||
690 | let text = c.text().to_string(); | ||
691 | Literal::String(text) | ||
692 | } | ||
693 | LiteralFlavor::Byte => { | ||
694 | let character = c.text().char_at(1).unwrap_or('X'); | ||
695 | Literal::Int(character as u8 as u64, UncertainIntTy::Unsigned(UintTy::U8)) | ||
696 | } | ||
697 | LiteralFlavor::Bool => Literal::Bool(true), | ||
698 | LiteralFlavor::Char => { | ||
699 | let character = c.text().char_at(1).unwrap_or('X'); | ||
700 | Literal::Char(character) | ||
701 | } | ||
702 | }; | ||
703 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) | ||
739 | } | 704 | } |
740 | 705 | ||
741 | // TODO implement HIR for these: | 706 | // TODO implement HIR for these: |