Skip to content

Commit faf4350

Browse files
committed
Add select stmts support for replace_let_with_if_let
- And migrate `edit_in_place::Indent` into `edit::AstNodeEdit` Example --- ```rust enum E<T> { X(T), Y(T) } fn main() { $0let x = E::X(92); let y = x;$0 let _ = (); } ``` **Before this PR** ``` enum E<T> { X(T), Y(T) } fn main() { if let x = E::X(92) { } let y = x; let _ = (); } ``` **After this PR** ```rust enum E<T> { X(T), Y(T) } fn main() { if let x = E::X(92) { let y = x; } let _ = (); } ```
1 parent c83c1a5 commit faf4350

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

crates/ide-assists/src/handlers/replace_let_with_if_let.rs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use ide_db::ty_filter::TryEnum;
22
use syntax::{
33
AstNode, T,
4-
ast::{self, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory},
4+
ast::{self, edit::AstNodeEdit, edit::IndentLevel, syntax_factory::SyntaxFactory},
55
};
66

77
use crate::{AssistContext, AssistId, Assists};
@@ -35,6 +35,11 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_>
3535
let let_stmt = let_kw.parent().and_then(ast::LetStmt::cast)?;
3636
let init = let_stmt.initializer()?;
3737
let original_pat = let_stmt.pat()?;
38+
let statements =
39+
std::iter::successors(let_stmt.syntax().next_sibling(), |it| it.next_sibling())
40+
.filter_map(ast::Stmt::cast)
41+
.filter(|stmt| crate::utils::is_selected(stmt, ctx.selection_trimmed(), false))
42+
.collect::<Vec<_>>();
3843

3944
let target = let_kw.text_range();
4045
acc.add(
@@ -63,16 +68,23 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_>
6368
let init_expr =
6469
if let_expr_needs_paren(&init) { make.expr_paren(init).into() } else { init };
6570

66-
let block = make.block_expr([], None);
67-
block.indent(IndentLevel::from_node(let_stmt.syntax()));
71+
let block = make.block_expr(statements.iter().map(AstNodeEdit::reset_indent), None);
6872
let if_expr = make.expr_if(
6973
make.expr_let(pat, init_expr).into(),
70-
block,
74+
block.indent(IndentLevel::from_node(let_stmt.syntax())),
7175
let_stmt
7276
.let_else()
7377
.and_then(|let_else| let_else.block_expr().map(ast::ElseBranch::from)),
7478
);
7579
let if_stmt = make.expr_stmt(if_expr.into());
80+
for stmt in statements {
81+
if let Some(prev) = stmt.syntax().prev_sibling_or_token()
82+
&& prev.kind() == syntax::SyntaxKind::WHITESPACE
83+
{
84+
editor.delete(prev);
85+
}
86+
editor.delete(stmt.syntax());
87+
}
7688

7789
editor.replace(let_stmt.syntax(), if_stmt.syntax());
7890
editor.add_mappings(make.finish_with_mappings());
@@ -119,6 +131,32 @@ fn main() {
119131
)
120132
}
121133

134+
#[test]
135+
fn replace_let_with_stmts() {
136+
check_assist(
137+
replace_let_with_if_let,
138+
r"
139+
enum E<T> { X(T), Y(T) }
140+
141+
fn main() {
142+
$0let x = E::X(92);
143+
let y = x;$0
144+
let _ = ();
145+
}
146+
",
147+
r"
148+
enum E<T> { X(T), Y(T) }
149+
150+
fn main() {
151+
if let x = E::X(92) {
152+
let y = x;
153+
}
154+
let _ = ();
155+
}
156+
",
157+
)
158+
}
159+
122160
#[test]
123161
fn replace_let_logic_and() {
124162
check_assist(

0 commit comments

Comments
 (0)