From 4fc233a02e8dc07619a969400c445ec47c2b1a9d Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Sat, 5 Jan 2019 21:28:30 +0100 Subject: Implement type inference for boolean operators --- crates/ra_syntax/src/ast.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'crates/ra_syntax/src/ast.rs') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index c10169d90..1bce6fa40 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -488,6 +488,45 @@ impl<'a> PrefixExpr<'a> { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum BinOp { + /// The `||` operator for boolean OR + BooleanOr, + /// The `&&` operator for boolean AND + BooleanAnd, + /// The `==` operator for equality testing + EqualityTest, + /// The `<=` operator for lesser-equal testing + LesserEqualTest, + /// The `>=` operator for greater-equal testing + GreaterEqualTest, + /// The `<` operator for comparison + LesserTest, + /// The `>` operator for comparison + GreaterTest, + // TODO: lots of others +} + +impl<'a> BinExpr<'a> { + pub fn op(&self) -> Option { + self.syntax() + .children() + .filter_map(|c| { + match c.kind() { + PIPEPIPE => Some(BinOp::BooleanOr), + AMPAMP => Some(BinOp::BooleanAnd), + EQEQ => Some(BinOp::EqualityTest), + LTEQ => Some(BinOp::LesserEqualTest), + GTEQ => Some(BinOp::GreaterEqualTest), + L_ANGLE => Some(BinOp::LesserTest), + R_ANGLE => Some(BinOp::GreaterTest), + _ => None, + } + }) + .next() + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum SelfParamFlavor { /// self -- cgit v1.2.3 From 82d9a77dade454ee8d09f198fa839e7755ff7bfb Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Sun, 6 Jan 2019 21:39:36 +0100 Subject: Touch up type inference for boolean operators Also try to infer its subexpressions and set type expectations whenever possible. --- crates/ra_syntax/src/ast.rs | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'crates/ra_syntax/src/ast.rs') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 1bce6fa40..9df8ec663 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -511,20 +511,33 @@ impl<'a> BinExpr<'a> { pub fn op(&self) -> Option { self.syntax() .children() - .filter_map(|c| { - match c.kind() { - PIPEPIPE => Some(BinOp::BooleanOr), - AMPAMP => Some(BinOp::BooleanAnd), - EQEQ => Some(BinOp::EqualityTest), - LTEQ => Some(BinOp::LesserEqualTest), - GTEQ => Some(BinOp::GreaterEqualTest), - L_ANGLE => Some(BinOp::LesserTest), - R_ANGLE => Some(BinOp::GreaterTest), - _ => None, - } + .filter_map(|c| match c.kind() { + PIPEPIPE => Some(BinOp::BooleanOr), + AMPAMP => Some(BinOp::BooleanAnd), + EQEQ => Some(BinOp::EqualityTest), + LTEQ => Some(BinOp::LesserEqualTest), + GTEQ => Some(BinOp::GreaterEqualTest), + L_ANGLE => Some(BinOp::LesserTest), + R_ANGLE => Some(BinOp::GreaterTest), + _ => None, }) .next() } + + pub fn lhs(self) -> Option> { + children(self).nth(0) + } + + pub fn rhs(self) -> Option> { + children(self).nth(1) + } + + pub fn sub_exprs(self) -> (Option>, Option>) { + let mut children = children(self); + let first = children.next(); + let second = children.next(); + (first, second) + } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -- cgit v1.2.3