From 99e9e52fbc9c3b18241e3db874daba6321508018 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 13 Apr 2022 16:01:09 +0200 Subject: [PATCH] Remove trailing `;` when turning assignment into `==` comparison --- crates/ide/src/typing.rs | 71 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index 99e7e3287d..24d4073170 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs @@ -173,6 +173,9 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option { if let Some(edit) = assign_expr(file, offset) { return Some(edit); } + if let Some(edit) = assign_to_eq(file, offset) { + return Some(edit); + } return None; @@ -182,13 +185,13 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option { return None; } + // Parent must be `ExprStmt` or `StmtList` for `;` to be valid. if let Some(expr_stmt) = ast::ExprStmt::cast(binop.syntax().parent()?) { if expr_stmt.semicolon_token().is_some() { return None; } } else { if !ast::StmtList::can_cast(binop.syntax().parent()?.kind()) { - // Parent must be `ExprStmt` or `StmtList` for `;` to be valid. return None; } } @@ -205,6 +208,25 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option { Some(TextEdit::insert(offset, ";".to_string())) } + /// `a =$0 b;` removes the semicolon if an expression is valid in this context. + fn assign_to_eq(file: &SourceFile, offset: TextSize) -> Option { + let binop: ast::BinExpr = find_node_at_offset(file.syntax(), offset)?; + if !matches!(binop.op_kind(), Some(ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated: false }))) + { + return None; + } + + let expr_stmt = ast::ExprStmt::cast(binop.syntax().parent()?)?; + let semi = expr_stmt.semicolon_token()?; + + if expr_stmt.syntax().next_sibling().is_some() { + // Not the last statement in the list. + return None; + } + + Some(TextEdit::delete(semi.text_range())) + } + fn let_stmt(file: &SourceFile, offset: TextSize) -> Option { let let_stmt: ast::LetStmt = find_node_at_offset(file.syntax(), offset)?; if let_stmt.semicolon_token().is_some() { @@ -424,6 +446,53 @@ fn f() { ); } + #[test] + fn assign_to_eq() { + type_char( + '=', + r#" +fn f(a: u8) { + a =$0 0; +} +"#, + r#" +fn f(a: u8) { + a == 0 +} +"#, + ); + type_char( + '=', + r#" +fn f(a: u8) { + a $0= 0; +} +"#, + r#" +fn f(a: u8) { + a == 0 +} +"#, + ); + type_char_noop( + '=', + r#" +fn f(a: u8) { + let e = a =$0 0; +} +"#, + ); + type_char_noop( + '=', + r#" +fn f(a: u8) { + let e = a =$0 0; + e +} +"#, + ); + } + #[test] fn indents_new_chain_call() { type_char(