mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-31 17:12:53 +00:00
Merge #1036
1036: Assist to flip equality (==) and negated equality (!=) operands. r=matklad a=marcogroppo This PR adds an assist to flip the equality operands. I hope this is the right way to do this (I'm a newbie...) Fixes #1023. Co-authored-by: Marco Groppo <marco.groppo@gmail.com>
This commit is contained in:
commit
965363db15
86
crates/ra_assists/src/flip_eq_operands.rs
Normal file
86
crates/ra_assists/src/flip_eq_operands.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use hir::db::HirDatabase;
|
||||
use ra_syntax::ast::{AstNode, BinExpr, BinOp};
|
||||
|
||||
use crate::{AssistCtx, Assist, AssistId};
|
||||
|
||||
pub(crate) fn flip_eq_operands(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
|
||||
let expr = ctx.node_at_offset::<BinExpr>()?;
|
||||
let lhs = expr.lhs()?.syntax();
|
||||
let rhs = expr.rhs()?.syntax();
|
||||
let op_range = expr.op()?.range();
|
||||
let cursor_in_range = ctx.frange.range.is_subrange(&op_range);
|
||||
let allowed_ops = [BinOp::EqualityTest, BinOp::NegatedEqualityTest];
|
||||
let expr_op = expr.op_kind()?;
|
||||
if !cursor_in_range || !allowed_ops.iter().any(|o| *o == expr_op) {
|
||||
return None;
|
||||
}
|
||||
ctx.add_action(AssistId("flip_eq_operands"), "flip equality operands", |edit| {
|
||||
edit.target(op_range);
|
||||
edit.replace(lhs.range(), rhs.text());
|
||||
edit.replace(rhs.range(), lhs.text());
|
||||
});
|
||||
|
||||
ctx.build()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::helpers::{check_assist, check_assist_target};
|
||||
|
||||
#[test]
|
||||
fn flip_eq_operands_for_simple_stmt() {
|
||||
check_assist(
|
||||
flip_eq_operands,
|
||||
"fn f() { let res = 1 ==<|> 2; }",
|
||||
"fn f() { let res = 2 ==<|> 1; }",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flip_neq_operands_for_simple_stmt() {
|
||||
check_assist(
|
||||
flip_eq_operands,
|
||||
"fn f() { let res = 1 !=<|> 2; }",
|
||||
"fn f() { let res = 2 !=<|> 1; }",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flip_eq_operands_for_complex_stmt() {
|
||||
check_assist(
|
||||
flip_eq_operands,
|
||||
"fn f() { let res = (1 + 1) ==<|> (2 + 2); }",
|
||||
"fn f() { let res = (2 + 2) ==<|> (1 + 1); }",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flip_eq_operands_in_match_expr() {
|
||||
check_assist(
|
||||
flip_eq_operands,
|
||||
r#"
|
||||
fn dyn_eq(&self, other: &dyn Diagnostic) -> bool {
|
||||
match other.downcast_ref::<Self>() {
|
||||
None => false,
|
||||
Some(it) => it ==<|> self,
|
||||
}
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn dyn_eq(&self, other: &dyn Diagnostic) -> bool {
|
||||
match other.downcast_ref::<Self>() {
|
||||
None => false,
|
||||
Some(it) => self ==<|> it,
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flip_eq_operands_target() {
|
||||
check_assist_target(flip_eq_operands, "fn f() { let res = 1 ==<|> 2; }", "==")
|
||||
}
|
||||
}
|
@ -88,6 +88,7 @@ where
|
||||
mod add_derive;
|
||||
mod add_impl;
|
||||
mod flip_comma;
|
||||
mod flip_eq_operands;
|
||||
mod change_visibility;
|
||||
mod fill_match_arms;
|
||||
mod fill_struct_fields;
|
||||
@ -106,6 +107,7 @@ fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assis
|
||||
fill_match_arms::fill_match_arms,
|
||||
fill_struct_fields::fill_struct_fields,
|
||||
flip_comma::flip_comma,
|
||||
flip_eq_operands::flip_eq_operands,
|
||||
introduce_variable::introduce_variable,
|
||||
replace_if_let_with_match::replace_if_let_with_match,
|
||||
split_import::split_import,
|
||||
|
@ -680,7 +680,7 @@ impl ExprCollector {
|
||||
}
|
||||
ast::ExprKind::PrefixExpr(e) => {
|
||||
let expr = self.collect_expr_opt(e.expr());
|
||||
if let Some(op) = e.op() {
|
||||
if let Some(op) = e.op_kind() {
|
||||
self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
|
||||
} else {
|
||||
self.alloc_expr(Expr::Missing, syntax_ptr)
|
||||
@ -703,7 +703,7 @@ impl ExprCollector {
|
||||
ast::ExprKind::BinExpr(e) => {
|
||||
let lhs = self.collect_expr_opt(e.lhs());
|
||||
let rhs = self.collect_expr_opt(e.rhs());
|
||||
let op = e.op();
|
||||
let op = e.op_kind();
|
||||
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
|
||||
}
|
||||
ast::ExprKind::TupleExpr(e) => {
|
||||
|
@ -521,7 +521,7 @@ pub enum PrefixOp {
|
||||
}
|
||||
|
||||
impl PrefixExpr {
|
||||
pub fn op(&self) -> Option<PrefixOp> {
|
||||
pub fn op_kind(&self) -> Option<PrefixOp> {
|
||||
match self.syntax().first_child()?.kind() {
|
||||
STAR => Some(PrefixOp::Deref),
|
||||
EXCL => Some(PrefixOp::Not),
|
||||
@ -529,6 +529,10 @@ impl PrefixExpr {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn op(&self) -> Option<&SyntaxNode> {
|
||||
self.syntax().first_child()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
@ -598,46 +602,54 @@ pub enum BinOp {
|
||||
}
|
||||
|
||||
impl BinExpr {
|
||||
pub fn op(&self) -> Option<BinOp> {
|
||||
fn op_details(&self) -> Option<(&SyntaxNode, BinOp)> {
|
||||
self.syntax()
|
||||
.children()
|
||||
.filter_map(|c| match c.kind() {
|
||||
PIPEPIPE => Some(BinOp::BooleanOr),
|
||||
AMPAMP => Some(BinOp::BooleanAnd),
|
||||
EQEQ => Some(BinOp::EqualityTest),
|
||||
NEQ => Some(BinOp::NegatedEqualityTest),
|
||||
LTEQ => Some(BinOp::LesserEqualTest),
|
||||
GTEQ => Some(BinOp::GreaterEqualTest),
|
||||
L_ANGLE => Some(BinOp::LesserTest),
|
||||
R_ANGLE => Some(BinOp::GreaterTest),
|
||||
PLUS => Some(BinOp::Addition),
|
||||
STAR => Some(BinOp::Multiplication),
|
||||
MINUS => Some(BinOp::Subtraction),
|
||||
SLASH => Some(BinOp::Division),
|
||||
PERCENT => Some(BinOp::Remainder),
|
||||
SHL => Some(BinOp::LeftShift),
|
||||
SHR => Some(BinOp::RightShift),
|
||||
CARET => Some(BinOp::BitwiseXor),
|
||||
PIPE => Some(BinOp::BitwiseOr),
|
||||
AMP => Some(BinOp::BitwiseAnd),
|
||||
DOTDOT => Some(BinOp::RangeRightOpen),
|
||||
DOTDOTEQ => Some(BinOp::RangeRightClosed),
|
||||
EQ => Some(BinOp::Assignment),
|
||||
PLUSEQ => Some(BinOp::AddAssign),
|
||||
SLASHEQ => Some(BinOp::DivAssign),
|
||||
STAREQ => Some(BinOp::MulAssign),
|
||||
PERCENTEQ => Some(BinOp::RemAssign),
|
||||
SHREQ => Some(BinOp::ShrAssign),
|
||||
SHLEQ => Some(BinOp::ShlAssign),
|
||||
MINUSEQ => Some(BinOp::SubAssign),
|
||||
PIPEEQ => Some(BinOp::BitOrAssign),
|
||||
AMPEQ => Some(BinOp::BitAndAssign),
|
||||
CARETEQ => Some(BinOp::BitXorAssign),
|
||||
PIPEPIPE => Some((c, BinOp::BooleanOr)),
|
||||
AMPAMP => Some((c, BinOp::BooleanAnd)),
|
||||
EQEQ => Some((c, BinOp::EqualityTest)),
|
||||
NEQ => Some((c, BinOp::NegatedEqualityTest)),
|
||||
LTEQ => Some((c, BinOp::LesserEqualTest)),
|
||||
GTEQ => Some((c, BinOp::GreaterEqualTest)),
|
||||
L_ANGLE => Some((c, BinOp::LesserTest)),
|
||||
R_ANGLE => Some((c, BinOp::GreaterTest)),
|
||||
PLUS => Some((c, BinOp::Addition)),
|
||||
STAR => Some((c, BinOp::Multiplication)),
|
||||
MINUS => Some((c, BinOp::Subtraction)),
|
||||
SLASH => Some((c, BinOp::Division)),
|
||||
PERCENT => Some((c, BinOp::Remainder)),
|
||||
SHL => Some((c, BinOp::LeftShift)),
|
||||
SHR => Some((c, BinOp::RightShift)),
|
||||
CARET => Some((c, BinOp::BitwiseXor)),
|
||||
PIPE => Some((c, BinOp::BitwiseOr)),
|
||||
AMP => Some((c, BinOp::BitwiseAnd)),
|
||||
DOTDOT => Some((c, BinOp::RangeRightOpen)),
|
||||
DOTDOTEQ => Some((c, BinOp::RangeRightClosed)),
|
||||
EQ => Some((c, BinOp::Assignment)),
|
||||
PLUSEQ => Some((c, BinOp::AddAssign)),
|
||||
SLASHEQ => Some((c, BinOp::DivAssign)),
|
||||
STAREQ => Some((c, BinOp::MulAssign)),
|
||||
PERCENTEQ => Some((c, BinOp::RemAssign)),
|
||||
SHREQ => Some((c, BinOp::ShrAssign)),
|
||||
SHLEQ => Some((c, BinOp::ShlAssign)),
|
||||
MINUSEQ => Some((c, BinOp::SubAssign)),
|
||||
PIPEEQ => Some((c, BinOp::BitOrAssign)),
|
||||
AMPEQ => Some((c, BinOp::BitAndAssign)),
|
||||
CARETEQ => Some((c, BinOp::BitXorAssign)),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn op_kind(&self) -> Option<BinOp> {
|
||||
self.op_details().map(|t| t.1)
|
||||
}
|
||||
|
||||
pub fn op(&self) -> Option<&SyntaxNode> {
|
||||
self.op_details().map(|t| t.0)
|
||||
}
|
||||
|
||||
pub fn lhs(&self) -> Option<&Expr> {
|
||||
children(self).nth(0)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user