fix(ide-assists): unwrap block when it parent is let stmt
This commit is contained in:
parent
8fa69f9f7d
commit
90b1222b0b
@ -2,6 +2,7 @@
|
|||||||
ast::{
|
ast::{
|
||||||
self,
|
self,
|
||||||
edit::{AstNodeEdit, IndentLevel},
|
edit::{AstNodeEdit, IndentLevel},
|
||||||
|
make,
|
||||||
},
|
},
|
||||||
AstNode, SyntaxKind, TextRange, T,
|
AstNode, SyntaxKind, TextRange, T,
|
||||||
};
|
};
|
||||||
@ -37,61 +38,89 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
|
|||||||
parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
|
parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(parent.kind(), SyntaxKind::STMT_LIST | SyntaxKind::EXPR_STMT | SyntaxKind::LET_STMT)
|
let kind = parent.kind();
|
||||||
{
|
if matches!(kind, SyntaxKind::STMT_LIST | SyntaxKind::EXPR_STMT) {
|
||||||
return acc.add(assist_id, assist_label, target, |builder| {
|
acc.add(assist_id, assist_label, target, |builder| {
|
||||||
builder.replace(block.syntax().text_range(), update_expr_string(block.to_string()));
|
builder.replace(block.syntax().text_range(), update_expr_string(block.to_string()));
|
||||||
});
|
})
|
||||||
}
|
} else if matches!(kind, SyntaxKind::LET_STMT) {
|
||||||
|
let parent = ast::LetStmt::cast(parent)?;
|
||||||
|
let pattern = ast::Pat::cast(parent.syntax().first_child()?)?;
|
||||||
|
let ty = parent.ty();
|
||||||
|
let list = block.stmt_list()?;
|
||||||
|
let replaced = match list.syntax().last_child() {
|
||||||
|
Some(last) => {
|
||||||
|
let stmts: Vec<ast::Stmt> = list.statements().collect();
|
||||||
|
let initializer = ast::Expr::cast(last.clone())?;
|
||||||
|
let let_stmt = make::let_stmt(pattern, ty, Some(initializer));
|
||||||
|
if stmts.len() > 0 {
|
||||||
|
let block = make::block_expr(stmts, None);
|
||||||
|
format!(
|
||||||
|
"{}\n {}",
|
||||||
|
update_expr_string(block.to_string()),
|
||||||
|
let_stmt.to_string()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let_stmt.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let empty_tuple = make::expr_tuple([]);
|
||||||
|
make::let_stmt(pattern, ty, Some(empty_tuple)).to_string()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
acc.add(assist_id, assist_label, target, |builder| {
|
||||||
|
builder.replace(parent.syntax().text_range(), replaced);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let parent = ast::Expr::cast(parent)?;
|
||||||
|
match parent.clone() {
|
||||||
|
ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
|
||||||
|
ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
|
||||||
|
ast::Expr::IfExpr(if_expr) => {
|
||||||
|
let then_branch = if_expr.then_branch()?;
|
||||||
|
if then_branch == block {
|
||||||
|
if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
|
||||||
|
// For `else if` blocks
|
||||||
|
let ancestor_then_branch = ancestor.then_branch()?;
|
||||||
|
|
||||||
let parent = ast::Expr::cast(parent)?;
|
return acc.add(assist_id, assist_label, target, |edit| {
|
||||||
|
let range_to_del_else_if = TextRange::new(
|
||||||
match parent.clone() {
|
ancestor_then_branch.syntax().text_range().end(),
|
||||||
ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
|
l_curly_token.text_range().start(),
|
||||||
ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
|
);
|
||||||
ast::Expr::IfExpr(if_expr) => {
|
let range_to_del_rest = TextRange::new(
|
||||||
let then_branch = if_expr.then_branch()?;
|
then_branch.syntax().text_range().end(),
|
||||||
if then_branch == block {
|
if_expr.syntax().text_range().end(),
|
||||||
if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
|
);
|
||||||
// For `else if` blocks
|
|
||||||
let ancestor_then_branch = ancestor.then_branch()?;
|
|
||||||
|
|
||||||
|
edit.delete(range_to_del_rest);
|
||||||
|
edit.delete(range_to_del_else_if);
|
||||||
|
edit.replace(
|
||||||
|
target,
|
||||||
|
update_expr_string_without_newline(then_branch.to_string()),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return acc.add(assist_id, assist_label, target, |edit| {
|
return acc.add(assist_id, assist_label, target, |edit| {
|
||||||
let range_to_del_else_if = TextRange::new(
|
let range_to_del = TextRange::new(
|
||||||
ancestor_then_branch.syntax().text_range().end(),
|
then_branch.syntax().text_range().end(),
|
||||||
l_curly_token.text_range().start(),
|
l_curly_token.text_range().start(),
|
||||||
);
|
);
|
||||||
let range_to_del_rest = TextRange::new(
|
|
||||||
then_branch.syntax().text_range().end(),
|
|
||||||
if_expr.syntax().text_range().end(),
|
|
||||||
);
|
|
||||||
|
|
||||||
edit.delete(range_to_del_rest);
|
edit.delete(range_to_del);
|
||||||
edit.delete(range_to_del_else_if);
|
edit.replace(target, update_expr_string_without_newline(block.to_string()));
|
||||||
edit.replace(
|
|
||||||
target,
|
|
||||||
update_expr_string_without_newline(then_branch.to_string()),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return acc.add(assist_id, assist_label, target, |edit| {
|
|
||||||
let range_to_del = TextRange::new(
|
|
||||||
then_branch.syntax().text_range().end(),
|
|
||||||
l_curly_token.text_range().start(),
|
|
||||||
);
|
|
||||||
|
|
||||||
edit.delete(range_to_del);
|
|
||||||
edit.replace(target, update_expr_string_without_newline(block.to_string()));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
_ => return None,
|
||||||
_ => return None,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
acc.add(assist_id, assist_label, target, |builder| {
|
acc.add(assist_id, assist_label, target, |builder| {
|
||||||
builder.replace(parent.syntax().text_range(), update_expr_string(block.to_string()));
|
builder.replace(parent.syntax().text_range(), update_expr_string(block.to_string()));
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_expr_string(expr_string: String) -> String {
|
fn update_expr_string(expr_string: String) -> String {
|
||||||
@ -724,6 +753,19 @@ fn unwrap_block_in_let_initializers() {
|
|||||||
check_assist(
|
check_assist(
|
||||||
unwrap_block,
|
unwrap_block,
|
||||||
r#"
|
r#"
|
||||||
|
fn main() {
|
||||||
|
let x = {$0};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
let x = ();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist(
|
||||||
|
unwrap_block,
|
||||||
|
r#"
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = {$0
|
let x = {$0
|
||||||
bar
|
bar
|
||||||
@ -734,6 +776,34 @@ fn main() {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let x = bar;
|
let x = bar;
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist(
|
||||||
|
unwrap_block,
|
||||||
|
r#"
|
||||||
|
fn main() -> i32 {
|
||||||
|
let _ = {$01; 2};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() -> i32 {
|
||||||
|
1;
|
||||||
|
let _ = 2;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist(
|
||||||
|
unwrap_block,
|
||||||
|
r#"
|
||||||
|
fn main() -> i32 {
|
||||||
|
let mut a = {$01; 2};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() -> i32 {
|
||||||
|
1;
|
||||||
|
let mut a = 2;
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user