From 7e5a186c1fe585aac95019addc963bf74cb112ae Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 17 Aug 2019 17:42:41 +0300 Subject: Introduce separate hir::BinaryOp Unlike ast::BinOp, it has significantly more structure to it, so it's easier to, say, handle all assignment-like operations in the same way. --- crates/ra_hir/src/expr.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index f33676655..ea3fa4417 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -257,7 +257,44 @@ pub enum Expr { Literal(Literal), } -pub use ra_syntax::ast::BinOp as BinaryOp; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum BinaryOp { + LogicOp(LogicOp), + ArithOp(ArithOp), + CmpOp(CmpOp), + Assignment { op: Option }, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum LogicOp { + And, + Or, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum CmpOp { + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum ArithOp { + Add, + Mul, + Sub, + Div, + Rem, + Shl, + Shr, + BitXor, + BitOr, + BitAnd, +} + pub use ra_syntax::ast::PrefixOp as UnaryOp; #[derive(Debug, Clone, Eq, PartialEq)] pub enum Array { @@ -791,7 +828,7 @@ where ast::ExprKind::BinExpr(e) => { let lhs = self.collect_expr_opt(e.lhs()); let rhs = self.collect_expr_opt(e.rhs()); - let op = e.op_kind(); + let op = e.op_kind().map(BinaryOp::from); self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) } ast::ExprKind::TupleExpr(e) => { @@ -1038,6 +1075,42 @@ where } } +impl From for BinaryOp { + fn from(ast_op: ast::BinOp) -> Self { + match ast_op { + ast::BinOp::BooleanOr => BinaryOp::LogicOp(LogicOp::Or), + ast::BinOp::BooleanAnd => BinaryOp::LogicOp(LogicOp::And), + ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Equal), + ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::NotEqual), + ast::BinOp::LesserEqualTest => BinaryOp::CmpOp(CmpOp::LessOrEqual), + ast::BinOp::GreaterEqualTest => BinaryOp::CmpOp(CmpOp::GreaterOrEqual), + ast::BinOp::LesserTest => BinaryOp::CmpOp(CmpOp::Less), + ast::BinOp::GreaterTest => BinaryOp::CmpOp(CmpOp::Greater), + ast::BinOp::Addition => BinaryOp::ArithOp(ArithOp::Add), + ast::BinOp::Multiplication => BinaryOp::ArithOp(ArithOp::Mul), + ast::BinOp::Subtraction => BinaryOp::ArithOp(ArithOp::Sub), + ast::BinOp::Division => BinaryOp::ArithOp(ArithOp::Div), + ast::BinOp::Remainder => BinaryOp::ArithOp(ArithOp::Rem), + ast::BinOp::LeftShift => BinaryOp::ArithOp(ArithOp::Shl), + ast::BinOp::RightShift => BinaryOp::ArithOp(ArithOp::Shr), + ast::BinOp::BitwiseXor => BinaryOp::ArithOp(ArithOp::BitXor), + ast::BinOp::BitwiseOr => BinaryOp::ArithOp(ArithOp::BitOr), + ast::BinOp::BitwiseAnd => BinaryOp::ArithOp(ArithOp::BitAnd), + ast::BinOp::Assignment => BinaryOp::Assignment { op: None }, + ast::BinOp::AddAssign => BinaryOp::Assignment { op: Some(ArithOp::Add) }, + ast::BinOp::DivAssign => BinaryOp::Assignment { op: Some(ArithOp::Div) }, + ast::BinOp::MulAssign => BinaryOp::Assignment { op: Some(ArithOp::Mul) }, + ast::BinOp::RemAssign => BinaryOp::Assignment { op: Some(ArithOp::Rem) }, + ast::BinOp::ShlAssign => BinaryOp::Assignment { op: Some(ArithOp::Shl) }, + ast::BinOp::ShrAssign => BinaryOp::Assignment { op: Some(ArithOp::Shr) }, + ast::BinOp::SubAssign => BinaryOp::Assignment { op: Some(ArithOp::Sub) }, + ast::BinOp::BitOrAssign => BinaryOp::Assignment { op: Some(ArithOp::BitOr) }, + ast::BinOp::BitAndAssign => BinaryOp::Assignment { op: Some(ArithOp::BitAnd) }, + ast::BinOp::BitXorAssign => BinaryOp::Assignment { op: Some(ArithOp::BitXor) }, + } + } +} + pub(crate) fn body_with_source_map_query( db: &impl HirDatabase, def: DefWithBody, -- cgit v1.2.3 From b082cd679ad1ae7646d03261bcccda435443365c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 17 Aug 2019 17:51:01 +0300 Subject: normalize ordering ops --- crates/ra_hir/src/expr.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index ea3fa4417..5430a0c9f 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -273,12 +273,14 @@ pub enum LogicOp { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum CmpOp { - Equal, - NotEqual, + Eq { negated: bool }, + Ord { ordering: Ordering, strict: bool }, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum Ordering { Less, - LessOrEqual, Greater, - GreaterOrEqual, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -1080,12 +1082,20 @@ impl From for BinaryOp { match ast_op { ast::BinOp::BooleanOr => BinaryOp::LogicOp(LogicOp::Or), ast::BinOp::BooleanAnd => BinaryOp::LogicOp(LogicOp::And), - ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Equal), - ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::NotEqual), - ast::BinOp::LesserEqualTest => BinaryOp::CmpOp(CmpOp::LessOrEqual), - ast::BinOp::GreaterEqualTest => BinaryOp::CmpOp(CmpOp::GreaterOrEqual), - ast::BinOp::LesserTest => BinaryOp::CmpOp(CmpOp::Less), - ast::BinOp::GreaterTest => BinaryOp::CmpOp(CmpOp::Greater), + ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: false }), + ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: true }), + ast::BinOp::LesserEqualTest => { + BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: false }) + } + ast::BinOp::GreaterEqualTest => { + BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: false }) + } + ast::BinOp::LesserTest => { + BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: true }) + } + ast::BinOp::GreaterTest => { + BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: true }) + } ast::BinOp::Addition => BinaryOp::ArithOp(ArithOp::Add), ast::BinOp::Multiplication => BinaryOp::ArithOp(ArithOp::Mul), ast::BinOp::Subtraction => BinaryOp::ArithOp(ArithOp::Sub), -- cgit v1.2.3 From 189d879659f4e44c3343023d6455bed7cdf0e7c9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 17 Aug 2019 18:05:20 +0300 Subject: implement initial type inference for index expressions --- crates/ra_hir/src/expr.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir/src/expr.rs') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 5430a0c9f..a16561d11 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -245,6 +245,10 @@ pub enum Expr { rhs: ExprId, op: Option, }, + Index { + base: ExprId, + index: ExprId, + }, Lambda { args: Vec, arg_types: Vec>, @@ -399,6 +403,10 @@ impl Expr { f(*lhs); f(*rhs); } + Expr::Index { base, index } => { + f(*base); + f(*index); + } Expr::Field { expr, .. } | Expr::Await { expr } | Expr::Try { expr } @@ -887,10 +895,14 @@ where }; self.alloc_expr(Expr::Literal(lit), syntax_ptr) } + ast::ExprKind::IndexExpr(e) => { + let base = self.collect_expr_opt(e.base()); + let index = self.collect_expr_opt(e.index()); + self.alloc_expr(Expr::Index { base, index }, syntax_ptr) + } // FIXME implement HIR for these: ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), - ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::ExprKind::MacroCall(e) => { let ast_id = self -- cgit v1.2.3