mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Simplify unwrapping of blocks
This commit is contained in:
parent
733ef3163c
commit
5233766ce5
@ -1,8 +1,5 @@
|
|||||||
use ra_fmt::unwrap_trivial_block;
|
use ra_fmt::unwrap_trivial_block;
|
||||||
use ra_syntax::{
|
use ra_syntax::{ast, AstNode, TextRange, T};
|
||||||
ast::{self, ElseBranch, Expr, LoopBodyOwner},
|
|
||||||
match_ast, AstNode, TextRange, T,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{AssistContext, AssistId, Assists};
|
use crate::{AssistContext, AssistId, Assists};
|
||||||
|
|
||||||
@ -29,89 +26,62 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
|||||||
let parent = block.syntax().parent()?;
|
let parent = block.syntax().parent()?;
|
||||||
let assist_id = AssistId("unwrap_block");
|
let assist_id = AssistId("unwrap_block");
|
||||||
let assist_label = "Unwrap block";
|
let assist_label = "Unwrap block";
|
||||||
|
let parent = ast::Expr::cast(parent)?;
|
||||||
|
|
||||||
let (expr, expr_to_unwrap) = match_ast! {
|
match parent.clone() {
|
||||||
match parent {
|
ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
|
||||||
ast::ForExpr(for_expr) => {
|
ast::Expr::IfExpr(if_expr) => {
|
||||||
let block_expr = for_expr.loop_body()?;
|
let then_branch = if_expr.then_branch()?;
|
||||||
let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?;
|
if then_branch == block {
|
||||||
(ast::Expr::ForExpr(for_expr), expr_to_unwrap)
|
if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
|
||||||
},
|
// For `else if` blocks
|
||||||
ast::WhileExpr(while_expr) => {
|
let ancestor_then_branch = ancestor.then_branch()?;
|
||||||
let block_expr = while_expr.loop_body()?;
|
|
||||||
let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?;
|
|
||||||
(ast::Expr::WhileExpr(while_expr), expr_to_unwrap)
|
|
||||||
},
|
|
||||||
ast::LoopExpr(loop_expr) => {
|
|
||||||
let block_expr = loop_expr.loop_body()?;
|
|
||||||
let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?;
|
|
||||||
(ast::Expr::LoopExpr(loop_expr), expr_to_unwrap)
|
|
||||||
},
|
|
||||||
ast::IfExpr(if_expr) => {
|
|
||||||
let mut resp = None;
|
|
||||||
|
|
||||||
let then_branch = if_expr.then_branch()?;
|
let target = then_branch.syntax().text_range();
|
||||||
if then_branch.l_curly_token()?.text_range().contains_range(ctx.frange.range) {
|
return acc.add(assist_id, assist_label, target, |edit| {
|
||||||
if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
|
let range_to_del_else_if = TextRange::new(
|
||||||
// For `else if` blocks
|
ancestor_then_branch.syntax().text_range().end(),
|
||||||
let ancestor_then_branch = ancestor.then_branch()?;
|
l_curly_token.text_range().start(),
|
||||||
let l_curly_token = then_branch.l_curly_token()?;
|
);
|
||||||
|
let range_to_del_rest = TextRange::new(
|
||||||
|
then_branch.syntax().text_range().end(),
|
||||||
|
if_expr.syntax().text_range().end(),
|
||||||
|
);
|
||||||
|
|
||||||
let target = then_branch.syntax().text_range();
|
edit.delete(range_to_del_rest);
|
||||||
return acc.add(assist_id, assist_label, target, |edit| {
|
edit.delete(range_to_del_else_if);
|
||||||
let range_to_del_else_if = TextRange::new(ancestor_then_branch.syntax().text_range().end(), l_curly_token.text_range().start());
|
edit.replace(
|
||||||
let range_to_del_rest = TextRange::new(then_branch.syntax().text_range().end(), if_expr.syntax().text_range().end());
|
target,
|
||||||
|
update_expr_string(then_branch.to_string(), &[' ', '{']),
|
||||||
edit.delete(range_to_del_rest);
|
);
|
||||||
edit.delete(range_to_del_else_if);
|
});
|
||||||
edit.replace(target, update_expr_string(then_branch.to_string(), &[' ', '{']));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
resp = Some((ast::Expr::IfExpr(if_expr.clone()), Expr::BlockExpr(then_branch)));
|
|
||||||
}
|
|
||||||
} else if let Some(else_branch) = if_expr.else_branch() {
|
|
||||||
match else_branch {
|
|
||||||
ElseBranch::Block(else_block) => {
|
|
||||||
let l_curly_token = else_block.l_curly_token()?;
|
|
||||||
if l_curly_token.text_range().contains_range(ctx.frange.range) {
|
|
||||||
let target = else_block.syntax().text_range();
|
|
||||||
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(else_block.to_string(), &[' ', '{']));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ElseBranch::IfExpr(_) => {},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let target = block.syntax().text_range();
|
||||||
|
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(),
|
||||||
|
);
|
||||||
|
|
||||||
resp?
|
edit.delete(range_to_del);
|
||||||
},
|
edit.replace(target, update_expr_string(block.to_string(), &[' ', '{']));
|
||||||
_ => return None,
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = expr_to_unwrap.syntax().text_range();
|
let unwrapped = unwrap_trivial_block(block);
|
||||||
acc.add(assist_id, assist_label, target, |edit| {
|
let target = unwrapped.syntax().text_range();
|
||||||
edit.replace(
|
acc.add(assist_id, assist_label, target, |builder| {
|
||||||
expr.syntax().text_range(),
|
builder.replace(
|
||||||
update_expr_string(expr_to_unwrap.to_string(), &[' ', '{', '\n']),
|
parent.syntax().text_range(),
|
||||||
|
update_expr_string(unwrapped.to_string(), &[' ', '{', '\n']),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_expr(cursor_range: TextRange, block: ast::BlockExpr) -> Option<ast::Expr> {
|
|
||||||
let cursor_in_range = block.l_curly_token()?.text_range().contains_range(cursor_range);
|
|
||||||
|
|
||||||
if cursor_in_range {
|
|
||||||
Some(unwrap_trivial_block(block))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_expr_string(expr_str: String, trim_start_pat: &[char]) -> String {
|
fn update_expr_string(expr_str: String, trim_start_pat: &[char]) -> String {
|
||||||
let expr_string = expr_str.trim_start_matches(trim_start_pat);
|
let expr_string = expr_str.trim_start_matches(trim_start_pat);
|
||||||
let mut expr_string_lines: Vec<&str> = expr_string.lines().collect();
|
let mut expr_string_lines: Vec<&str> = expr_string.lines().collect();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user