mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
internal: merge hir::BinaryOp and ast::BinOp
This commit is contained in:
parent
fe4f059450
commit
90357a9090
12 changed files with 160 additions and 233 deletions
|
@ -27,8 +27,8 @@ use crate::{
|
|||
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
|
||||
db::DefDatabase,
|
||||
expr::{
|
||||
dummy_expr_id, Array, BinaryOp, BindingAnnotation, Expr, ExprId, Label, LabelId, Literal,
|
||||
MatchArm, MatchGuard, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
|
||||
dummy_expr_id, Array, BindingAnnotation, Expr, ExprId, Label, LabelId, Literal, MatchArm,
|
||||
MatchGuard, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
|
||||
},
|
||||
intern::Interned,
|
||||
item_scope::BuiltinShadowMode,
|
||||
|
@ -508,7 +508,7 @@ impl ExprCollector<'_> {
|
|||
ast::Expr::BinExpr(e) => {
|
||||
let lhs = self.collect_expr_opt(e.lhs());
|
||||
let rhs = self.collect_expr_opt(e.rhs());
|
||||
let op = e.op_kind().map(BinaryOp::from);
|
||||
let op = e.op_kind();
|
||||
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
|
||||
}
|
||||
ast::Expr::TupleExpr(e) => {
|
||||
|
|
|
@ -26,7 +26,13 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
|||
let expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
|
||||
let op = expr.op_kind()?;
|
||||
let op_range = expr.op_token()?.text_range();
|
||||
let opposite_op = opposite_logic_op(op)?;
|
||||
|
||||
let opposite_op = match op {
|
||||
ast::BinaryOp::LogicOp(ast::LogicOp::And) => "||",
|
||||
ast::BinaryOp::LogicOp(ast::LogicOp::Or) => "&&",
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let cursor_in_range = op_range.contains_range(ctx.frange.range);
|
||||
if !cursor_in_range {
|
||||
return None;
|
||||
|
@ -136,15 +142,6 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
|||
)
|
||||
}
|
||||
|
||||
// Return the opposite text for a given logical operator, if it makes sense
|
||||
fn opposite_logic_op(kind: ast::BinOp) -> Option<&'static str> {
|
||||
match kind {
|
||||
ast::BinOp::BooleanOr => Some("&&"),
|
||||
ast::BinOp::BooleanAnd => Some("||"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::tests::{check_assist, check_assist_not_applicable};
|
||||
|
|
|
@ -892,7 +892,7 @@ fn expr_require_exclusive_access(ctx: &AssistContext, expr: &ast::Expr) -> Optio
|
|||
let parent = expr.syntax().parent()?;
|
||||
|
||||
if let Some(bin_expr) = ast::BinExpr::cast(parent.clone()) {
|
||||
if bin_expr.op_kind()?.is_assignment() {
|
||||
if matches!(bin_expr.op_kind()?, ast::BinaryOp::Assignment { .. }) {
|
||||
return Some(bin_expr.lhs()?.syntax() == expr.syntax());
|
||||
}
|
||||
return Some(false);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use syntax::ast::{AstNode, BinExpr, BinOp};
|
||||
use syntax::ast::{self, AstNode, BinExpr};
|
||||
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
|
@ -56,14 +56,19 @@ enum FlipAction {
|
|||
DontFlip,
|
||||
}
|
||||
|
||||
impl From<BinOp> for FlipAction {
|
||||
fn from(op_kind: BinOp) -> Self {
|
||||
impl From<ast::BinaryOp> for FlipAction {
|
||||
fn from(op_kind: ast::BinaryOp) -> Self {
|
||||
match op_kind {
|
||||
kind if kind.is_assignment() => FlipAction::DontFlip,
|
||||
BinOp::GreaterTest => FlipAction::FlipAndReplaceOp("<"),
|
||||
BinOp::GreaterEqualTest => FlipAction::FlipAndReplaceOp("<="),
|
||||
BinOp::LesserTest => FlipAction::FlipAndReplaceOp(">"),
|
||||
BinOp::LesserEqualTest => FlipAction::FlipAndReplaceOp(">="),
|
||||
ast::BinaryOp::Assignment { .. } => FlipAction::DontFlip,
|
||||
ast::BinaryOp::CmpOp(ast::CmpOp::Ord { ordering, strict }) => {
|
||||
let rev_op = match (ordering, strict) {
|
||||
(ast::Ordering::Less, true) => ">",
|
||||
(ast::Ordering::Less, false) => ">=",
|
||||
(ast::Ordering::Greater, true) => "<",
|
||||
(ast::Ordering::Greater, false) => "<=",
|
||||
};
|
||||
FlipAction::FlipAndReplaceOp(rev_op)
|
||||
}
|
||||
_ => FlipAction::Flip,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti
|
|||
let assign_expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
|
||||
|
||||
let op_kind = assign_expr.op_kind()?;
|
||||
if op_kind != ast::BinOp::Assignment {
|
||||
if op_kind != (ast::BinaryOp::Assignment { op: None }) {
|
||||
cov_mark::hit!(test_cant_pull_non_assignments);
|
||||
return None;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ impl<'a> AssignmentsCollector<'a> {
|
|||
}
|
||||
|
||||
fn collect_expr(&mut self, expr: &ast::BinExpr) -> Option<()> {
|
||||
if expr.op_kind()? == ast::BinOp::Assignment
|
||||
if expr.op_kind()? == (ast::BinaryOp::Assignment { op: None })
|
||||
&& is_equivalent(self.sema, &expr.lhs()?, &self.common_lhs)
|
||||
{
|
||||
self.assignments.push((expr.clone(), expr.rhs()?));
|
||||
|
|
|
@ -210,12 +210,17 @@ pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr {
|
|||
fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
|
||||
match expr {
|
||||
ast::Expr::BinExpr(bin) => match bin.op_kind()? {
|
||||
ast::BinOp::NegatedEqualityTest => bin.replace_op(T![==]).map(|it| it.into()),
|
||||
ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()),
|
||||
ast::BinOp::LesserTest => bin.replace_op(T![>=]).map(|it| it.into()),
|
||||
ast::BinOp::LesserEqualTest => bin.replace_op(T![>]).map(|it| it.into()),
|
||||
ast::BinOp::GreaterTest => bin.replace_op(T![<=]).map(|it| it.into()),
|
||||
ast::BinOp::GreaterEqualTest => bin.replace_op(T![<]).map(|it| it.into()),
|
||||
ast::BinaryOp::CmpOp(op) => {
|
||||
let rev_op = match op {
|
||||
ast::CmpOp::Eq { negated: false } => T![!=],
|
||||
ast::CmpOp::Eq { negated: true } => T![==],
|
||||
ast::CmpOp::Ord { ordering: ast::Ordering::Less, strict: true } => T![>=],
|
||||
ast::CmpOp::Ord { ordering: ast::Ordering::Less, strict: false } => T![>],
|
||||
ast::CmpOp::Ord { ordering: ast::Ordering::Greater, strict: true } => T![<=],
|
||||
ast::CmpOp::Ord { ordering: ast::Ordering::Greater, strict: false } => T![<],
|
||||
};
|
||||
bin.replace_op(rev_op).map(ast::Expr::from)
|
||||
}
|
||||
// Parenthesize other expressions before prefixing `!`
|
||||
_ => Some(make::expr_prefix(T![!], make::expr_paren(expr.clone()))),
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! This module contains functions to generate default trait impl function bodies where possible.
|
||||
|
||||
use syntax::{
|
||||
ast::{self, edit::AstNodeEdit, make, AstNode, NameOwner},
|
||||
ast::{self, edit::AstNodeEdit, make, AstNode, BinaryOp, CmpOp, LogicOp, NameOwner},
|
||||
ted,
|
||||
};
|
||||
|
||||
|
@ -325,7 +325,7 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
|||
fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||
fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> {
|
||||
match expr {
|
||||
Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
|
||||
Some(expr) => Some(make::expr_bin_op(expr, BinaryOp::LogicOp(LogicOp::And), cmp)),
|
||||
None => Some(cmp),
|
||||
}
|
||||
}
|
||||
|
@ -362,7 +362,8 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
|||
let lhs = make::expr_call(make_discriminant()?, make::arg_list(Some(lhs_name.clone())));
|
||||
let rhs_name = make::expr_path(make::ext::ident_path("other"));
|
||||
let rhs = make::expr_call(make_discriminant()?, make::arg_list(Some(rhs_name.clone())));
|
||||
let eq_check = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
|
||||
let eq_check =
|
||||
make::expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
|
||||
|
||||
let mut case_count = 0;
|
||||
let mut arms = vec![];
|
||||
|
@ -386,7 +387,11 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
|||
|
||||
let lhs = make::expr_path(make::ext::ident_path(l_name));
|
||||
let rhs = make::expr_path(make::ext::ident_path(r_name));
|
||||
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
|
||||
let cmp = make::expr_bin_op(
|
||||
lhs,
|
||||
BinaryOp::CmpOp(CmpOp::Eq { negated: false }),
|
||||
rhs,
|
||||
);
|
||||
expr = gen_eq_chain(expr, cmp);
|
||||
}
|
||||
|
||||
|
@ -415,7 +420,11 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
|||
|
||||
let lhs = make::expr_path(make::ext::ident_path(&l_name));
|
||||
let rhs = make::expr_path(make::ext::ident_path(&r_name));
|
||||
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
|
||||
let cmp = make::expr_bin_op(
|
||||
lhs,
|
||||
BinaryOp::CmpOp(CmpOp::Eq { negated: false }),
|
||||
rhs,
|
||||
);
|
||||
expr = gen_eq_chain(expr, cmp);
|
||||
}
|
||||
|
||||
|
@ -455,7 +464,8 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
|||
let lhs = make::expr_field(lhs, &field.name()?.to_string());
|
||||
let rhs = make::expr_path(make::ext::ident_path("other"));
|
||||
let rhs = make::expr_field(rhs, &field.name()?.to_string());
|
||||
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
|
||||
let cmp =
|
||||
make::expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
|
||||
expr = gen_eq_chain(expr, cmp);
|
||||
}
|
||||
make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
|
||||
|
@ -469,7 +479,8 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
|||
let lhs = make::expr_field(lhs, &idx);
|
||||
let rhs = make::expr_path(make::ext::ident_path("other"));
|
||||
let rhs = make::expr_field(rhs, &idx);
|
||||
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
|
||||
let cmp =
|
||||
make::expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
|
||||
expr = gen_eq_chain(expr, cmp);
|
||||
}
|
||||
make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
|
||||
|
|
|
@ -655,7 +655,7 @@ fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<Referen
|
|||
match_ast! {
|
||||
match (node) {
|
||||
ast::BinExpr(expr) => {
|
||||
if expr.op_kind()?.is_assignment() {
|
||||
if matches!(expr.op_kind()?, ast::BinaryOp::Assignment { .. }) {
|
||||
// If the variable or field ends on the LHS's end then it's a Write (covers fields and locals).
|
||||
// FIXME: This is not terribly accurate.
|
||||
if let Some(lhs) = expr.lhs() {
|
||||
|
|
|
@ -18,13 +18,13 @@ use crate::{
|
|||
};
|
||||
|
||||
pub use self::{
|
||||
expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind},
|
||||
expr_ext::{ArrayExprKind, Effect, ElseBranch, LiteralKind},
|
||||
generated::{nodes::*, tokens::*},
|
||||
node_ext::{
|
||||
AttrKind, AttrsOwnerNode, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind,
|
||||
SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind,
|
||||
},
|
||||
operators::{ArithOp, BinaryOp, CmpOp, LogicOp, RangeOp, UnaryOp, Ordering},
|
||||
operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp},
|
||||
token_ext::{
|
||||
CommentKind, CommentPlacement, CommentShape, FormatSpecifier, HasFormatSpecifier, IsString,
|
||||
QuoteOffsets, Radix,
|
||||
|
|
|
@ -5,7 +5,7 @@ use rowan::WalkEvent;
|
|||
use crate::{
|
||||
ast::{
|
||||
self,
|
||||
operators::{RangeOp, UnaryOp},
|
||||
operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp},
|
||||
support, AstChildren, AstNode,
|
||||
},
|
||||
AstToken,
|
||||
|
@ -213,127 +213,51 @@ impl ast::PrefixExpr {
|
|||
}
|
||||
}
|
||||
|
||||
#[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 equality testing
|
||||
NegatedEqualityTest,
|
||||
/// The `<=` operator for lesser-equal testing
|
||||
LesserEqualTest,
|
||||
/// The `>=` operator for greater-equal testing
|
||||
GreaterEqualTest,
|
||||
/// The `<` operator for comparison
|
||||
LesserTest,
|
||||
/// The `>` operator for comparison
|
||||
GreaterTest,
|
||||
/// The `+` operator for addition
|
||||
Addition,
|
||||
/// The `*` operator for multiplication
|
||||
Multiplication,
|
||||
/// The `-` operator for subtraction
|
||||
Subtraction,
|
||||
/// The `/` operator for division
|
||||
Division,
|
||||
/// The `%` operator for remainder after division
|
||||
Remainder,
|
||||
/// The `<<` operator for left shift
|
||||
LeftShift,
|
||||
/// The `>>` operator for right shift
|
||||
RightShift,
|
||||
/// The `^` operator for bitwise XOR
|
||||
BitwiseXor,
|
||||
/// The `|` operator for bitwise OR
|
||||
BitwiseOr,
|
||||
/// The `&` operator for bitwise AND
|
||||
BitwiseAnd,
|
||||
/// The `=` operator for assignment
|
||||
Assignment,
|
||||
/// The `+=` operator for assignment after addition
|
||||
AddAssign,
|
||||
/// The `/=` operator for assignment after division
|
||||
DivAssign,
|
||||
/// The `*=` operator for assignment after multiplication
|
||||
MulAssign,
|
||||
/// The `%=` operator for assignment after remainders
|
||||
RemAssign,
|
||||
/// The `>>=` operator for assignment after shifting right
|
||||
ShrAssign,
|
||||
/// The `<<=` operator for assignment after shifting left
|
||||
ShlAssign,
|
||||
/// The `-=` operator for assignment after subtraction
|
||||
SubAssign,
|
||||
/// The `|=` operator for assignment after bitwise OR
|
||||
BitOrAssign,
|
||||
/// The `&=` operator for assignment after bitwise AND
|
||||
BitAndAssign,
|
||||
/// The `^=` operator for assignment after bitwise XOR
|
||||
BitXorAssign,
|
||||
}
|
||||
|
||||
impl BinOp {
|
||||
pub fn is_assignment(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
BinOp::Assignment
|
||||
| BinOp::AddAssign
|
||||
| BinOp::DivAssign
|
||||
| BinOp::MulAssign
|
||||
| BinOp::RemAssign
|
||||
| BinOp::ShrAssign
|
||||
| BinOp::ShlAssign
|
||||
| BinOp::SubAssign
|
||||
| BinOp::BitOrAssign
|
||||
| BinOp::BitAndAssign
|
||||
| BinOp::BitXorAssign
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::BinExpr {
|
||||
pub fn op_details(&self) -> Option<(SyntaxToken, BinOp)> {
|
||||
pub fn op_details(&self) -> Option<(SyntaxToken, BinaryOp)> {
|
||||
self.syntax().children_with_tokens().filter_map(|it| it.into_token()).find_map(|c| {
|
||||
#[rustfmt::skip]
|
||||
let bin_op = match c.kind() {
|
||||
T![||] => BinOp::BooleanOr,
|
||||
T![&&] => BinOp::BooleanAnd,
|
||||
T![==] => BinOp::EqualityTest,
|
||||
T![!=] => BinOp::NegatedEqualityTest,
|
||||
T![<=] => BinOp::LesserEqualTest,
|
||||
T![>=] => BinOp::GreaterEqualTest,
|
||||
T![<] => BinOp::LesserTest,
|
||||
T![>] => BinOp::GreaterTest,
|
||||
T![+] => BinOp::Addition,
|
||||
T![*] => BinOp::Multiplication,
|
||||
T![-] => BinOp::Subtraction,
|
||||
T![/] => BinOp::Division,
|
||||
T![%] => BinOp::Remainder,
|
||||
T![<<] => BinOp::LeftShift,
|
||||
T![>>] => BinOp::RightShift,
|
||||
T![^] => BinOp::BitwiseXor,
|
||||
T![|] => BinOp::BitwiseOr,
|
||||
T![&] => BinOp::BitwiseAnd,
|
||||
T![=] => BinOp::Assignment,
|
||||
T![+=] => BinOp::AddAssign,
|
||||
T![/=] => BinOp::DivAssign,
|
||||
T![*=] => BinOp::MulAssign,
|
||||
T![%=] => BinOp::RemAssign,
|
||||
T![>>=] => BinOp::ShrAssign,
|
||||
T![<<=] => BinOp::ShlAssign,
|
||||
T![-=] => BinOp::SubAssign,
|
||||
T![|=] => BinOp::BitOrAssign,
|
||||
T![&=] => BinOp::BitAndAssign,
|
||||
T![^=] => BinOp::BitXorAssign,
|
||||
T![||] => BinaryOp::LogicOp(LogicOp::Or),
|
||||
T![&&] => BinaryOp::LogicOp(LogicOp::And),
|
||||
|
||||
T![==] => BinaryOp::CmpOp(CmpOp::Eq { negated: false }),
|
||||
T![!=] => BinaryOp::CmpOp(CmpOp::Eq { negated: true }),
|
||||
T![<=] => BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: false }),
|
||||
T![>=] => BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: false }),
|
||||
T![<] => BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: true }),
|
||||
T![>] => BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: true }),
|
||||
|
||||
T![+] => BinaryOp::ArithOp(ArithOp::Add),
|
||||
T![*] => BinaryOp::ArithOp(ArithOp::Mul),
|
||||
T![-] => BinaryOp::ArithOp(ArithOp::Sub),
|
||||
T![/] => BinaryOp::ArithOp(ArithOp::Div),
|
||||
T![%] => BinaryOp::ArithOp(ArithOp::Rem),
|
||||
T![<<] => BinaryOp::ArithOp(ArithOp::Shl),
|
||||
T![>>] => BinaryOp::ArithOp(ArithOp::Shr),
|
||||
T![^] => BinaryOp::ArithOp(ArithOp::BitXor),
|
||||
T![|] => BinaryOp::ArithOp(ArithOp::BitOr),
|
||||
T![&] => BinaryOp::ArithOp(ArithOp::BitAnd),
|
||||
|
||||
T![=] => BinaryOp::Assignment { op: None },
|
||||
T![+=] => BinaryOp::Assignment { op: Some(ArithOp::Add) },
|
||||
T![*=] => BinaryOp::Assignment { op: Some(ArithOp::Mul) },
|
||||
T![-=] => BinaryOp::Assignment { op: Some(ArithOp::Sub) },
|
||||
T![/=] => BinaryOp::Assignment { op: Some(ArithOp::Div) },
|
||||
T![%=] => BinaryOp::Assignment { op: Some(ArithOp::Rem) },
|
||||
T![<<=] => BinaryOp::Assignment { op: Some(ArithOp::Shl) },
|
||||
T![>>=] => BinaryOp::Assignment { op: Some(ArithOp::Shr) },
|
||||
T![^=] => BinaryOp::Assignment { op: Some(ArithOp::BitXor) },
|
||||
T![|=] => BinaryOp::Assignment { op: Some(ArithOp::BitOr) },
|
||||
T![&=] => BinaryOp::Assignment { op: Some(ArithOp::BitAnd) },
|
||||
|
||||
_ => return None,
|
||||
};
|
||||
Some((c, bin_op))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn op_kind(&self) -> Option<BinOp> {
|
||||
pub fn op_kind(&self) -> Option<BinaryOp> {
|
||||
self.op_details().map(|t| t.1)
|
||||
}
|
||||
|
||||
|
@ -357,42 +281,6 @@ impl ast::BinExpr {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for BinOp {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
BinOp::BooleanOr => write!(f, "||"),
|
||||
BinOp::BooleanAnd => write!(f, "&&"),
|
||||
BinOp::EqualityTest => write!(f, "=="),
|
||||
BinOp::NegatedEqualityTest => write!(f, "!="),
|
||||
BinOp::LesserEqualTest => write!(f, "<="),
|
||||
BinOp::GreaterEqualTest => write!(f, ">="),
|
||||
BinOp::LesserTest => write!(f, "<"),
|
||||
BinOp::GreaterTest => write!(f, ">"),
|
||||
BinOp::Addition => write!(f, "+"),
|
||||
BinOp::Multiplication => write!(f, "*"),
|
||||
BinOp::Subtraction => write!(f, "-"),
|
||||
BinOp::Division => write!(f, "/"),
|
||||
BinOp::Remainder => write!(f, "%"),
|
||||
BinOp::LeftShift => write!(f, "<<"),
|
||||
BinOp::RightShift => write!(f, ">>"),
|
||||
BinOp::BitwiseXor => write!(f, "^"),
|
||||
BinOp::BitwiseOr => write!(f, "|"),
|
||||
BinOp::BitwiseAnd => write!(f, "&"),
|
||||
BinOp::Assignment => write!(f, "="),
|
||||
BinOp::AddAssign => write!(f, "+="),
|
||||
BinOp::DivAssign => write!(f, "/="),
|
||||
BinOp::MulAssign => write!(f, "*="),
|
||||
BinOp::RemAssign => write!(f, "%="),
|
||||
BinOp::ShrAssign => write!(f, ">>="),
|
||||
BinOp::ShlAssign => write!(f, "<<="),
|
||||
BinOp::SubAssign => write!(f, "-"),
|
||||
BinOp::BitOrAssign => write!(f, "|="),
|
||||
BinOp::BitAndAssign => write!(f, "&="),
|
||||
BinOp::BitXorAssign => write!(f, "^="),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::RangeExpr {
|
||||
fn op_details(&self) -> Option<(usize, SyntaxToken, RangeOp)> {
|
||||
self.syntax().children_with_tokens().enumerate().find_map(|(ix, child)| {
|
||||
|
|
|
@ -276,7 +276,8 @@ pub fn expr_path(path: ast::Path) -> ast::Expr {
|
|||
pub fn expr_continue() -> ast::Expr {
|
||||
expr_from_text("continue")
|
||||
}
|
||||
pub fn expr_op(op: ast::BinOp, lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
|
||||
// Consider `op: SyntaxKind` instead for nicer syntax at the call-site?
|
||||
pub fn expr_bin_op(lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::Expr {
|
||||
expr_from_text(&format!("{} {} {}", lhs, op, rhs))
|
||||
}
|
||||
pub fn expr_break(expr: Option<ast::Expr>) -> ast::Expr {
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
//! Defines a bunch of data-less enums for unary and binary operators.
|
||||
//!
|
||||
//! Types here don't know about AST, this allows re-using them for both AST and
|
||||
//! HIR.
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum RangeOp {
|
||||
/// `..`
|
||||
|
@ -8,11 +14,11 @@ pub enum RangeOp {
|
|||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum UnaryOp {
|
||||
/// The `*` operator for dereferencing
|
||||
/// `*`
|
||||
Deref,
|
||||
/// The `!` operator for logical inversion
|
||||
/// `!`
|
||||
Not,
|
||||
/// The `-` operator for negation
|
||||
/// `-`
|
||||
Neg,
|
||||
}
|
||||
|
||||
|
@ -56,47 +62,61 @@ pub enum ArithOp {
|
|||
BitAnd,
|
||||
}
|
||||
|
||||
use crate::ast;
|
||||
impl From<ast::BinOp> 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::Eq { negated: false }),
|
||||
ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: true }),
|
||||
ast::BinOp::LesserEqualTest => {
|
||||
BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: false })
|
||||
impl fmt::Display for LogicOp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let res = match self {
|
||||
LogicOp::And => "&&",
|
||||
LogicOp::Or => "||",
|
||||
};
|
||||
f.write_str(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ArithOp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let res = match self {
|
||||
ArithOp::Add => "+",
|
||||
ArithOp::Mul => "*",
|
||||
ArithOp::Sub => "-",
|
||||
ArithOp::Div => "/",
|
||||
ArithOp::Rem => "%",
|
||||
ArithOp::Shl => "<<",
|
||||
ArithOp::Shr => ">>",
|
||||
ArithOp::BitXor => "^",
|
||||
ArithOp::BitOr => "|",
|
||||
ArithOp::BitAnd => "&",
|
||||
};
|
||||
f.write_str(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CmpOp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let res = match self {
|
||||
CmpOp::Eq { negated: false } => "==",
|
||||
CmpOp::Eq { negated: true } => "!=",
|
||||
CmpOp::Ord { ordering: Ordering::Less, strict: false } => "<=",
|
||||
CmpOp::Ord { ordering: Ordering::Less, strict: true } => "<",
|
||||
CmpOp::Ord { ordering: Ordering::Greater, strict: false } => ">=",
|
||||
CmpOp::Ord { ordering: Ordering::Greater, strict: true } => ">",
|
||||
};
|
||||
f.write_str(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BinaryOp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
BinaryOp::LogicOp(op) => fmt::Display::fmt(op, f),
|
||||
BinaryOp::ArithOp(op) => fmt::Display::fmt(op, f),
|
||||
BinaryOp::CmpOp(op) => fmt::Display::fmt(op, f),
|
||||
BinaryOp::Assignment { op } => {
|
||||
f.write_str("=")?;
|
||||
if let Some(op) = op {
|
||||
fmt::Display::fmt(op, f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
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),
|
||||
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) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue