diff options
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index f0936e9f3..e07725d05 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -5,7 +5,10 @@ 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, Cancelable}; |
8 | use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}; | 8 | use ra_syntax::{ |
9 | SyntaxKind, | ||
10 | ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner} | ||
11 | }; | ||
9 | 12 | ||
10 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; | 13 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; |
11 | 14 | ||
@@ -104,6 +107,19 @@ impl BodySyntaxMapping { | |||
104 | } | 107 | } |
105 | 108 | ||
106 | #[derive(Debug, Clone, Eq, PartialEq)] | 109 | #[derive(Debug, Clone, Eq, PartialEq)] |
110 | pub enum Literal { | ||
111 | String(String), | ||
112 | ByteString(Vec<u8>), | ||
113 | Char(char), | ||
114 | Bool(bool), | ||
115 | Byte(u8), | ||
116 | Int, // this and float need additional information | ||
117 | Float, | ||
118 | Tuple { values: Vec<ExprId> }, | ||
119 | Array { values: Vec<ExprId> }, | ||
120 | } | ||
121 | |||
122 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
107 | pub enum Expr { | 123 | pub enum Expr { |
108 | /// This is produced if syntax tree does not have a required expression piece. | 124 | /// This is produced if syntax tree does not have a required expression piece. |
109 | Missing, | 125 | Missing, |
@@ -186,6 +202,7 @@ pub enum Expr { | |||
186 | Tuple { | 202 | Tuple { |
187 | exprs: Vec<ExprId>, | 203 | exprs: Vec<ExprId>, |
188 | }, | 204 | }, |
205 | Literal(Literal), | ||
189 | } | 206 | } |
190 | 207 | ||
191 | pub use ra_syntax::ast::PrefixOp as UnaryOp; | 208 | pub use ra_syntax::ast::PrefixOp as UnaryOp; |
@@ -305,6 +322,20 @@ impl Expr { | |||
305 | f(*expr); | 322 | f(*expr); |
306 | } | 323 | } |
307 | } | 324 | } |
325 | Expr::Literal(l) => match l { | ||
326 | Literal::Array { values } | Literal::Tuple { values } => { | ||
327 | for &val in values { | ||
328 | f(val); | ||
329 | } | ||
330 | } | ||
331 | Literal::String(..) | ||
332 | | Literal::ByteString(..) | ||
333 | | Literal::Byte(..) | ||
334 | | Literal::Bool(..) | ||
335 | | Literal::Char(..) | ||
336 | | Literal::Int | ||
337 | | Literal::Float => {} | ||
338 | }, | ||
308 | } | 339 | } |
309 | } | 340 | } |
310 | } | 341 | } |
@@ -633,13 +664,56 @@ impl ExprCollector { | |||
633 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 664 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); |
634 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 665 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
635 | } | 666 | } |
667 | ast::ExprKind::Literal(e) => { | ||
668 | let child = e.syntax().children().next(); | ||
669 | |||
670 | if let Some(c) = child { | ||
671 | let lit = match c.kind() { | ||
672 | SyntaxKind::INT_NUMBER => Literal::Int, | ||
673 | SyntaxKind::FLOAT_NUMBER => Literal::Float, | ||
674 | SyntaxKind::STRING => { | ||
675 | // FIXME: this likely includes the " characters | ||
676 | let text = c.text().to_string(); | ||
677 | Literal::String(text) | ||
678 | } | ||
679 | SyntaxKind::ARRAY_EXPR => { | ||
680 | // TODO: recursively call to self | ||
681 | Literal::Array { values: vec![] } | ||
682 | } | ||
683 | SyntaxKind::PAREN_EXPR => { | ||
684 | // TODO: recursively call to self | ||
685 | Literal::Tuple { values: vec![] } | ||
686 | } | ||
687 | SyntaxKind::TRUE_KW => Literal::Bool(true), | ||
688 | SyntaxKind::FALSE_KW => Literal::Bool(false), | ||
689 | SyntaxKind::BYTE_STRING => { | ||
690 | // FIXME: this is completely incorrect for a variety | ||
691 | // of reasons, but at least it gives the right type | ||
692 | let bytes = c.text().to_string().into_bytes(); | ||
693 | Literal::ByteString(bytes) | ||
694 | } | ||
695 | SyntaxKind::CHAR => { | ||
696 | let character = c.text().char_at(1).unwrap_or('X'); | ||
697 | Literal::Char(character) | ||
698 | } | ||
699 | SyntaxKind::BYTE => { | ||
700 | let character = c.text().char_at(1).unwrap_or('X'); | ||
701 | Literal::Byte(character as u8) | ||
702 | } | ||
703 | _ => return self.alloc_expr(Expr::Missing, syntax_ptr), | ||
704 | }; | ||
705 | |||
706 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) | ||
707 | } else { | ||
708 | self.alloc_expr(Expr::Missing, syntax_ptr) | ||
709 | } | ||
710 | } | ||
636 | 711 | ||
637 | // TODO implement HIR for these: | 712 | // TODO implement HIR for these: |
638 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 713 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
639 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 714 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
640 | ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 715 | ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
641 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 716 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
642 | ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
643 | } | 717 | } |
644 | } | 718 | } |
645 | 719 | ||