9993: feat: join lines merges assignments r=matklad a=unexge

Closes https://github.com/rust-analyzer/rust-analyzer/issues/9967.
![Peek 2021-08-22 21-46](https://user-images.githubusercontent.com/16212576/130366571-3ebb1753-f8d5-4884-be8f-222cda71a2a7.gif)


Co-authored-by: unexge <unexge@gmail.com>
This commit is contained in:
bors[bot] 2021-08-24 12:14:25 +00:00 committed by GitHub
commit 49c02b93b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 0 deletions

View file

@ -15,6 +15,7 @@ pub struct JoinLinesConfig {
pub join_else_if: bool,
pub remove_trailing_comma: bool,
pub unwrap_trivial_blocks: bool,
pub join_assignments: bool,
}
// Feature: Join Lines
@ -162,6 +163,12 @@ fn remove_newline(
}
}
if config.join_assignments {
if join_assignments(edit, &prev, &next).is_some() {
return;
}
}
if config.unwrap_trivial_blocks {
// Special case that turns something like:
//
@ -232,6 +239,41 @@ fn join_single_use_tree(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Opti
Some(())
}
fn join_assignments(
edit: &mut TextEditBuilder,
prev: &SyntaxElement,
next: &SyntaxElement,
) -> Option<()> {
let let_stmt = ast::LetStmt::cast(prev.as_node()?.clone())?;
if let_stmt.eq_token().is_some() {
cov_mark::hit!(join_assignments_already_initialized);
return None;
}
let let_ident_pat = match let_stmt.pat()? {
ast::Pat::IdentPat(it) => it,
_ => return None,
};
let expr_stmt = ast::ExprStmt::cast(next.as_node()?.clone())?;
let bin_expr = match expr_stmt.expr()? {
ast::Expr::BinExpr(it) => it,
_ => return None,
};
if !matches!(bin_expr.op_kind()?, ast::BinaryOp::Assignment { op: None }) {
return None;
}
let lhs = bin_expr.lhs()?;
let name_ref = lhs.name_ref()?;
if name_ref.to_string() != let_ident_pat.syntax().to_string() {
cov_mark::hit!(join_assignments_mismatch);
return None;
}
edit.delete(let_stmt.semicolon_token()?.text_range().cover(lhs.syntax().text_range()));
Some(())
}
fn as_if_expr(element: &SyntaxElement) -> Option<ast::IfExpr> {
let mut node = element.as_node()?.clone();
if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
@ -275,6 +317,7 @@ mod tests {
join_else_if: true,
remove_trailing_comma: true,
unwrap_trivial_blocks: true,
join_assignments: true,
};
let (before_cursor_pos, before) = extract_offset(ra_fixture_before);
@ -300,6 +343,7 @@ mod tests {
join_else_if: true,
remove_trailing_comma: true,
unwrap_trivial_blocks: true,
join_assignments: true,
};
let (sel, before) = extract_range(ra_fixture_before);
@ -990,6 +1034,55 @@ fn main() {
}
}
"#,
);
}
#[test]
fn join_assignments() {
check_join_lines(
r#"
fn foo() {
$0let foo;
foo = "bar";
}
"#,
r#"
fn foo() {
$0let foo = "bar";
}
"#,
);
cov_mark::check!(join_assignments_mismatch);
check_join_lines(
r#"
fn foo() {
let foo;
let qux;$0
foo = "bar";
}
"#,
r#"
fn foo() {
let foo;
let qux;$0 foo = "bar";
}
"#,
);
cov_mark::check!(join_assignments_already_initialized);
check_join_lines(
r#"
fn foo() {
let foo = "bar";$0
foo = "bar";
}
"#,
r#"
fn foo() {
let foo = "bar";$0 foo = "bar";
}
"#,
);
}

View file

@ -206,6 +206,8 @@ config_data! {
joinLines_removeTrailingComma: bool = "true",
/// Join lines unwraps trivial blocks.
joinLines_unwrapTrivialBlock: bool = "true",
/// Join lines merges consecutive declaration and initialization of an assignment.
joinLines_joinAssignments: bool = "true",
/// Whether to show `Debug` lens. Only applies when
/// `#rust-analyzer.lens.enable#` is set.
@ -786,6 +788,7 @@ impl Config {
join_else_if: self.data.joinLines_joinElseIf,
remove_trailing_comma: self.data.joinLines_removeTrailingComma,
unwrap_trivial_blocks: self.data.joinLines_unwrapTrivialBlock,
join_assignments: self.data.joinLines_joinAssignments,
}
}
pub fn call_info_full(&self) -> bool {

View file

@ -318,6 +318,11 @@ Join lines removes trailing commas.
--
Join lines unwraps trivial blocks.
--
[[rust-analyzer.joinLines.joinAssignments]]rust-analyzer.joinLines.joinAssignments (default: `true`)::
+
--
Join lines merges consecutive declaration and initialization of an assignment.
--
[[rust-analyzer.lens.debug]]rust-analyzer.lens.debug (default: `true`)::
+
--

View file

@ -761,6 +761,11 @@
"default": true,
"type": "boolean"
},
"rust-analyzer.joinLines.joinAssignments": {
"markdownDescription": "Join lines merges consecutive declaration and initialization of an assignment.",
"default": true,
"type": "boolean"
},
"rust-analyzer.lens.debug": {
"markdownDescription": "Whether to show `Debug` lens. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
"default": true,