aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/flip_eq_operands.rs23
-rw-r--r--crates/ra_hir/src/expr.rs4
-rw-r--r--crates/ra_syntax/src/ast.rs78
3 files changed, 58 insertions, 47 deletions
diff --git a/crates/ra_assists/src/flip_eq_operands.rs b/crates/ra_assists/src/flip_eq_operands.rs
index f9d1aad62..df0bb689d 100644
--- a/crates/ra_assists/src/flip_eq_operands.rs
+++ b/crates/ra_assists/src/flip_eq_operands.rs
@@ -1,24 +1,23 @@
1use hir::db::HirDatabase; 1use hir::db::HirDatabase;
2use ra_syntax::{ 2use ra_syntax::ast::{AstNode, BinExpr, BinOp};
3 ast::{AstNode, BinExpr, BinOp}
4};
5 3
6use crate::{AssistCtx, Assist, AssistId}; 4use crate::{AssistCtx, Assist, AssistId};
7 5
8pub(crate) fn flip_eq_operands(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 6pub(crate) fn flip_eq_operands(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
9 let expr = ctx.node_at_offset::<BinExpr>()?; 7 let expr = ctx.node_at_offset::<BinExpr>()?;
8 let lhs = expr.lhs()?.syntax();
9 let rhs = expr.rhs()?.syntax();
10 let op_range = expr.op()?.range();
11 let cursor_in_range = ctx.frange.range.is_subrange(&op_range);
10 let allowed_ops = [BinOp::EqualityTest, BinOp::NegatedEqualityTest]; 12 let allowed_ops = [BinOp::EqualityTest, BinOp::NegatedEqualityTest];
11 let expr_op = expr.op()?; 13 let expr_op = expr.op_kind()?;
12 if !allowed_ops.iter().any(|o| *o == expr_op) { 14 if !cursor_in_range || !allowed_ops.iter().any(|o| *o == expr_op) {
13 return None; 15 return None;
14 } 16 }
15 let node = expr.syntax();
16 let prev = node.first_child()?;
17 let next = node.last_child()?;
18 ctx.add_action(AssistId("flip_eq_operands"), "flip equality operands", |edit| { 17 ctx.add_action(AssistId("flip_eq_operands"), "flip equality operands", |edit| {
19 edit.target(node.range()); 18 edit.target(op_range);
20 edit.replace(prev.range(), next.text()); 19 edit.replace(lhs.range(), rhs.text());
21 edit.replace(next.range(), prev.text()); 20 edit.replace(rhs.range(), lhs.text());
22 }); 21 });
23 22
24 ctx.build() 23 ctx.build()
@@ -82,6 +81,6 @@ mod tests {
82 81
83 #[test] 82 #[test]
84 fn flip_eq_operands_target() { 83 fn flip_eq_operands_target() {
85 check_assist_target(flip_eq_operands, "fn f() { let res = 1 ==<|> 2; }", "1 == 2") 84 check_assist_target(flip_eq_operands, "fn f() { let res = 1 ==<|> 2; }", "==")
86 } 85 }
87} 86}
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 703d99d9b..c37fd0454 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -680,7 +680,7 @@ impl ExprCollector {
680 } 680 }
681 ast::ExprKind::PrefixExpr(e) => { 681 ast::ExprKind::PrefixExpr(e) => {
682 let expr = self.collect_expr_opt(e.expr()); 682 let expr = self.collect_expr_opt(e.expr());
683 if let Some(op) = e.op() { 683 if let Some(op) = e.op_kind() {
684 self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) 684 self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
685 } else { 685 } else {
686 self.alloc_expr(Expr::Missing, syntax_ptr) 686 self.alloc_expr(Expr::Missing, syntax_ptr)
@@ -703,7 +703,7 @@ impl ExprCollector {
703 ast::ExprKind::BinExpr(e) => { 703 ast::ExprKind::BinExpr(e) => {
704 let lhs = self.collect_expr_opt(e.lhs()); 704 let lhs = self.collect_expr_opt(e.lhs());
705 let rhs = self.collect_expr_opt(e.rhs()); 705 let rhs = self.collect_expr_opt(e.rhs());
706 let op = e.op(); 706 let op = e.op_kind();
707 self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) 707 self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
708 } 708 }
709 ast::ExprKind::TupleExpr(e) => { 709 ast::ExprKind::TupleExpr(e) => {
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index d8c2cb063..226208700 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -521,7 +521,7 @@ pub enum PrefixOp {
521} 521}
522 522
523impl PrefixExpr { 523impl PrefixExpr {
524 pub fn op(&self) -> Option<PrefixOp> { 524 pub fn op_kind(&self) -> Option<PrefixOp> {
525 match self.syntax().first_child()?.kind() { 525 match self.syntax().first_child()?.kind() {
526 STAR => Some(PrefixOp::Deref), 526 STAR => Some(PrefixOp::Deref),
527 EXCL => Some(PrefixOp::Not), 527 EXCL => Some(PrefixOp::Not),
@@ -529,6 +529,10 @@ impl PrefixExpr {
529 _ => None, 529 _ => None,
530 } 530 }
531 } 531 }
532
533 pub fn op(&self) -> Option<&SyntaxNode> {
534 self.syntax().first_child()
535 }
532} 536}
533 537
534#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] 538#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -598,46 +602,54 @@ pub enum BinOp {
598} 602}
599 603
600impl BinExpr { 604impl BinExpr {
601 pub fn op(&self) -> Option<BinOp> { 605 fn op_details(&self) -> Option<(&SyntaxNode, BinOp)> {
602 self.syntax() 606 self.syntax()
603 .children() 607 .children()
604 .filter_map(|c| match c.kind() { 608 .filter_map(|c| match c.kind() {
605 PIPEPIPE => Some(BinOp::BooleanOr), 609 PIPEPIPE => Some((c, BinOp::BooleanOr)),
606 AMPAMP => Some(BinOp::BooleanAnd), 610 AMPAMP => Some((c, BinOp::BooleanAnd)),
607 EQEQ => Some(BinOp::EqualityTest), 611 EQEQ => Some((c, BinOp::EqualityTest)),
608 NEQ => Some(BinOp::NegatedEqualityTest), 612 NEQ => Some((c, BinOp::NegatedEqualityTest)),
609 LTEQ => Some(BinOp::LesserEqualTest), 613 LTEQ => Some((c, BinOp::LesserEqualTest)),
610 GTEQ => Some(BinOp::GreaterEqualTest), 614 GTEQ => Some((c, BinOp::GreaterEqualTest)),
611 L_ANGLE => Some(BinOp::LesserTest), 615 L_ANGLE => Some((c, BinOp::LesserTest)),
612 R_ANGLE => Some(BinOp::GreaterTest), 616 R_ANGLE => Some((c, BinOp::GreaterTest)),
613 PLUS => Some(BinOp::Addition), 617 PLUS => Some((c, BinOp::Addition)),
614 STAR => Some(BinOp::Multiplication), 618 STAR => Some((c, BinOp::Multiplication)),
615 MINUS => Some(BinOp::Subtraction), 619 MINUS => Some((c, BinOp::Subtraction)),
616 SLASH => Some(BinOp::Division), 620 SLASH => Some((c, BinOp::Division)),
617 PERCENT => Some(BinOp::Remainder), 621 PERCENT => Some((c, BinOp::Remainder)),
618 SHL => Some(BinOp::LeftShift), 622 SHL => Some((c, BinOp::LeftShift)),
619 SHR => Some(BinOp::RightShift), 623 SHR => Some((c, BinOp::RightShift)),
620 CARET => Some(BinOp::BitwiseXor), 624 CARET => Some((c, BinOp::BitwiseXor)),
621 PIPE => Some(BinOp::BitwiseOr), 625 PIPE => Some((c, BinOp::BitwiseOr)),
622 AMP => Some(BinOp::BitwiseAnd), 626 AMP => Some((c, BinOp::BitwiseAnd)),
623 DOTDOT => Some(BinOp::RangeRightOpen), 627 DOTDOT => Some((c, BinOp::RangeRightOpen)),
624 DOTDOTEQ => Some(BinOp::RangeRightClosed), 628 DOTDOTEQ => Some((c, BinOp::RangeRightClosed)),
625 EQ => Some(BinOp::Assignment), 629 EQ => Some((c, BinOp::Assignment)),
626 PLUSEQ => Some(BinOp::AddAssign), 630 PLUSEQ => Some((c, BinOp::AddAssign)),
627 SLASHEQ => Some(BinOp::DivAssign), 631 SLASHEQ => Some((c, BinOp::DivAssign)),
628 STAREQ => Some(BinOp::MulAssign), 632 STAREQ => Some((c, BinOp::MulAssign)),
629 PERCENTEQ => Some(BinOp::RemAssign), 633 PERCENTEQ => Some((c, BinOp::RemAssign)),
630 SHREQ => Some(BinOp::ShrAssign), 634 SHREQ => Some((c, BinOp::ShrAssign)),
631 SHLEQ => Some(BinOp::ShlAssign), 635 SHLEQ => Some((c, BinOp::ShlAssign)),
632 MINUSEQ => Some(BinOp::SubAssign), 636 MINUSEQ => Some((c, BinOp::SubAssign)),
633 PIPEEQ => Some(BinOp::BitOrAssign), 637 PIPEEQ => Some((c, BinOp::BitOrAssign)),
634 AMPEQ => Some(BinOp::BitAndAssign), 638 AMPEQ => Some((c, BinOp::BitAndAssign)),
635 CARETEQ => Some(BinOp::BitXorAssign), 639 CARETEQ => Some((c, BinOp::BitXorAssign)),
636 _ => None, 640 _ => None,
637 }) 641 })
638 .next() 642 .next()
639 } 643 }
640 644
645 pub fn op_kind(&self) -> Option<BinOp> {
646 self.op_details().map(|t| t.1)
647 }
648
649 pub fn op(&self) -> Option<&SyntaxNode> {
650 self.op_details().map(|t| t.0)
651 }
652
641 pub fn lhs(&self) -> Option<&Expr> { 653 pub fn lhs(&self) -> Option<&Expr> {
642 children(self).nth(0) 654 children(self).nth(0)
643 } 655 }