Skip to content

Commit ff6b020

Browse files
committed
feat: Migrate flip_binexpr assist to SyntaxEditor
1 parent 0eed197 commit ff6b020

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use syntax::ast::{self, AstNode, BinExpr};
1+
use syntax::{
2+
ast::{self, syntax_factory::SyntaxFactory, AstNode, BinExpr},
3+
SyntaxKind, T,
4+
};
25

36
use crate::{AssistContext, AssistId, AssistKind, Assists};
47

@@ -19,22 +22,17 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
1922
// ```
2023
pub(crate) fn flip_binexpr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
2124
let expr = ctx.find_node_at_offset::<BinExpr>()?;
22-
let rhs = expr.rhs()?.syntax().clone();
23-
let lhs = expr.lhs()?.syntax().clone();
24-
25-
let lhs = if let Some(bin_expr) = BinExpr::cast(lhs.clone()) {
26-
if bin_expr.op_kind() == expr.op_kind() {
27-
bin_expr.rhs()?.syntax().clone()
28-
} else {
29-
lhs
30-
}
31-
} else {
32-
lhs
25+
let lhs = expr.lhs()?;
26+
let rhs = expr.rhs()?;
27+
28+
let lhs = match &lhs {
29+
ast::Expr::BinExpr(bin_expr) if bin_expr.op_kind() == expr.op_kind() => bin_expr.rhs()?,
30+
_ => lhs,
3331
};
3432

35-
let op_range = expr.op_token()?.text_range();
33+
let op_token = expr.op_token()?;
3634
// The assist should be applied only if the cursor is on the operator
37-
let cursor_in_range = op_range.contains_range(ctx.selection_trimmed());
35+
let cursor_in_range = op_token.text_range().contains_range(ctx.selection_trimmed());
3836
if !cursor_in_range {
3937
return None;
4038
}
@@ -47,13 +45,18 @@ pub(crate) fn flip_binexpr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
4745
acc.add(
4846
AssistId("flip_binexpr", AssistKind::RefactorRewrite),
4947
"Flip binary expression",
50-
op_range,
51-
|edit| {
52-
if let FlipAction::FlipAndReplaceOp(new_op) = action {
53-
edit.replace(op_range, new_op);
54-
}
55-
edit.replace(lhs.text_range(), rhs.text());
56-
edit.replace(rhs.text_range(), lhs.text());
48+
op_token.text_range(),
49+
|builder| {
50+
let mut editor = builder.make_editor(&expr.syntax().parent().unwrap());
51+
let make = SyntaxFactory::new();
52+
if let FlipAction::FlipAndReplaceOp(binary_op) = action {
53+
editor.replace(op_token, make.token(binary_op))
54+
};
55+
// FIXME: remove `clone_for_update` when `SyntaxEditor` handles it for us
56+
editor.replace(lhs.syntax(), rhs.syntax().clone_for_update());
57+
editor.replace(rhs.syntax(), lhs.syntax().clone_for_update());
58+
editor.add_mappings(make.finish_with_mappings());
59+
builder.add_file_edits(ctx.file_id(), editor);
5760
},
5861
)
5962
}
@@ -62,7 +65,7 @@ enum FlipAction {
6265
// Flip the expression
6366
Flip,
6467
// Flip the expression and replace the operator with this string
65-
FlipAndReplaceOp(&'static str),
68+
FlipAndReplaceOp(SyntaxKind),
6669
// Do not flip the expression
6770
DontFlip,
6871
}
@@ -73,10 +76,10 @@ impl From<ast::BinaryOp> for FlipAction {
7376
ast::BinaryOp::Assignment { .. } => FlipAction::DontFlip,
7477
ast::BinaryOp::CmpOp(ast::CmpOp::Ord { ordering, strict }) => {
7578
let rev_op = match (ordering, strict) {
76-
(ast::Ordering::Less, true) => ">",
77-
(ast::Ordering::Less, false) => ">=",
78-
(ast::Ordering::Greater, true) => "<",
79-
(ast::Ordering::Greater, false) => "<=",
79+
(ast::Ordering::Less, true) => T![>],
80+
(ast::Ordering::Less, false) => T![>=],
81+
(ast::Ordering::Greater, true) => T![<],
82+
(ast::Ordering::Greater, false) => T![<=],
8083
};
8184
FlipAction::FlipAndReplaceOp(rev_op)
8285
}

0 commit comments

Comments
 (0)