Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/add_braces.rs')
-rw-r--r--crates/ide-assists/src/handlers/add_braces.rs121
1 files changed, 100 insertions, 21 deletions
diff --git a/crates/ide-assists/src/handlers/add_braces.rs b/crates/ide-assists/src/handlers/add_braces.rs
index 5af622eaf2..99ee50fa58 100644
--- a/crates/ide-assists/src/handlers/add_braces.rs
+++ b/crates/ide-assists/src/handlers/add_braces.rs
@@ -1,14 +1,15 @@
use either::Either;
use syntax::{
- AstNode,
- ast::{self, edit_in_place::Indent, syntax_factory::SyntaxFactory},
+ AstNode, T,
+ ast::{self, edit::AstNodeEdit, syntax_factory::SyntaxFactory},
+ match_ast,
};
use crate::{AssistContext, AssistId, Assists};
// Assist: add_braces
//
-// Adds braces to closure bodies and match arm expressions.
+// Adds braces to closure bodies, match arm expressions and assignment bodies.
//
// ```
// fn foo(n: i32) -> i32 {
@@ -29,6 +30,20 @@ use crate::{AssistContext, AssistId, Assists};
// }
// }
// ```
+// ---
+// ```
+// fn foo(n: i32) -> i32 {
+// let x =$0 n + 2;
+// }
+// ```
+// ->
+// ```
+// fn foo(n: i32) -> i32 {
+// let x = {
+// n + 2
+// };
+// }
+// ```
pub(crate) fn add_braces(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
let (expr_type, expr) = get_replacement_node(ctx)?;
@@ -37,16 +52,17 @@ pub(crate) fn add_braces(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
match expr_type {
ParentType::ClosureExpr => "Add braces to this closure body",
ParentType::MatchArmExpr => "Add braces to this match arm expression",
+ ParentType::Assignment => "Add braces to this assignment expression",
},
expr.syntax().text_range(),
|builder| {
let make = SyntaxFactory::with_mappings();
let mut editor = builder.make_editor(expr.syntax());
- let block_expr = make.block_expr(None, Some(expr.clone()));
- block_expr.indent(expr.indent_level());
+ let new_expr = expr.reset_indent().indent(1.into());
+ let block_expr = make.block_expr(None, Some(new_expr));
- editor.replace(expr.syntax(), block_expr.syntax());
+ editor.replace(expr.syntax(), block_expr.indent(expr.indent_level()).syntax());
editor.add_mappings(make.finish_with_mappings());
builder.add_file_edits(ctx.vfs_file_id(), editor);
@@ -57,29 +73,38 @@ pub(crate) fn add_braces(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
enum ParentType {
MatchArmExpr,
ClosureExpr,
+ Assignment,
}
fn get_replacement_node(ctx: &AssistContext<'_>) -> Option<(ParentType, ast::Expr)> {
- let node = ctx.find_node_at_offset::<Either<ast::MatchArm, ast::ClosureExpr>>()?;
- if let Either::Left(match_arm) = &node {
+ let node = ctx.find_node_at_offset::<Either<ast::MatchArm, ast::ClosureExpr>>();
+ let (parent_type, body) = if let Some(eq_token) = ctx.find_token_syntax_at_offset(T![=]) {
+ let parent = eq_token.parent()?;
+ let body = match_ast! {
+ match parent {
+ ast::LetStmt(it) => it.initializer()?,
+ ast::LetExpr(it) => it.expr()?,
+ ast::Static(it) => it.body()?,
+ ast::Const(it) => it.body()?,
+ _ => return None,
+ }
+ };
+ (ParentType::Assignment, body)
+ } else if let Some(Either::Left(match_arm)) = &node {
let match_arm_expr = match_arm.expr()?;
-
- if matches!(match_arm_expr, ast::Expr::BlockExpr(_)) {
- return None;
- }
-
- return Some((ParentType::MatchArmExpr, match_arm_expr));
- } else if let Either::Right(closure_expr) = &node {
+ (ParentType::MatchArmExpr, match_arm_expr)
+ } else if let Some(Either::Right(closure_expr)) = &node {
let body = closure_expr.body()?;
+ (ParentType::ClosureExpr, body)
+ } else {
+ return None;
+ };
- if matches!(body, ast::Expr::BlockExpr(_)) {
- return None;
- }
-
- return Some((ParentType::ClosureExpr, body));
+ if matches!(body, ast::Expr::BlockExpr(_)) {
+ return None;
}
- None
+ Some((parent_type, body))
}
#[cfg(test)]
@@ -135,6 +160,25 @@ fn foo() {
}
#[test]
+ fn suggest_add_braces_for_assignment() {
+ check_assist(
+ add_braces,
+ r#"
+fn foo() {
+ let x =$0 n + 100;
+}
+"#,
+ r#"
+fn foo() {
+ let x = {
+ n + 100
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
fn no_assist_for_closures_with_braces() {
check_assist_not_applicable(
add_braces,
@@ -172,6 +216,41 @@ fn foo() {
}
#[test]
+ fn multiple_indent() {
+ check_assist(
+ add_braces,
+ r#"
+fn foo() {
+ {
+ match n {
+ Some(n) $0=> foo(
+ 29,
+ 30,
+ ),
+ _ => ()
+ };
+ }
+}
+"#,
+ r#"
+fn foo() {
+ {
+ match n {
+ Some(n) => {
+ foo(
+ 29,
+ 30,
+ )
+ },
+ _ => ()
+ };
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
fn no_assist_for_match_with_braces() {
check_assist_not_applicable(
add_braces,