Skip to content

Commit 8d0fa9c

Browse files
bors[bot]matklad
andauthored
Merge #9473
9473: feat: join lines joins two ifs into `else if` r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 668d061 + f875b91 commit 8d0fa9c

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

crates/ide/src/join_lines.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use itertools::Itertools;
55
use syntax::{
66
algo::non_trivia_sibling,
77
ast::{self, AstNode, AstToken, IsString},
8-
Direction, NodeOrToken, SourceFile,
8+
Direction, NodeOrToken, SourceFile, SyntaxElement,
99
SyntaxKind::{self, USE_TREE, WHITESPACE},
1010
SyntaxNode, SyntaxToken, TextRange, TextSize, T,
1111
};
@@ -107,6 +107,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextS
107107
edit.delete(TextRange::new(prev.text_range().start(), token.text_range().end()));
108108
return;
109109
}
110+
110111
if prev.kind() == T![,] && next.kind() == T!['}'] {
111112
// Removes: comma, newline (incl. surrounding whitespace)
112113
let space = if let Some(left) = prev.prev_sibling_or_token() {
@@ -133,6 +134,17 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextS
133134
return;
134135
}
135136

137+
if let (Some(prev), Some(_next)) = (as_if_expr(&prev), as_if_expr(&next)) {
138+
match prev.else_token() {
139+
Some(_) => cov_mark::hit!(join_two_ifs_with_existing_else),
140+
None => {
141+
cov_mark::hit!(join_two_ifs);
142+
edit.replace(token.text_range(), " else ".to_string());
143+
return;
144+
}
145+
}
146+
}
147+
136148
// Special case that turns something like:
137149
//
138150
// ```
@@ -200,6 +212,14 @@ fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool {
200212
matches!((left, right), (T![,], T![')'] | T![']']))
201213
}
202214

215+
fn as_if_expr(element: &SyntaxElement) -> Option<ast::IfExpr> {
216+
let mut node = element.as_node()?.clone();
217+
if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
218+
node = stmt.expr()?.syntax().clone();
219+
}
220+
ast::IfExpr::cast(node)
221+
}
222+
203223
fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str {
204224
match left {
205225
T!['('] | T!['['] => return "",
@@ -873,6 +893,7 @@ $0hello world
873893
"#,
874894
);
875895
}
896+
876897
#[test]
877898
fn join_last_line_empty() {
878899
check_join_lines(
@@ -881,6 +902,62 @@ fn main() {$0}
881902
"#,
882903
r#"
883904
fn main() {$0}
905+
"#,
906+
);
907+
}
908+
909+
#[test]
910+
fn join_two_ifs() {
911+
cov_mark::check!(join_two_ifs);
912+
check_join_lines(
913+
r#"
914+
fn main() {
915+
if foo {
916+
917+
}$0
918+
if bar {
919+
920+
}
921+
}
922+
"#,
923+
r#"
924+
fn main() {
925+
if foo {
926+
927+
}$0 else if bar {
928+
929+
}
930+
}
931+
"#,
932+
);
933+
}
934+
935+
#[test]
936+
fn join_two_ifs_with_existing_else() {
937+
cov_mark::check!(join_two_ifs_with_existing_else);
938+
check_join_lines(
939+
r#"
940+
fn main() {
941+
if foo {
942+
943+
} else {
944+
945+
}$0
946+
if bar {
947+
948+
}
949+
}
950+
"#,
951+
r#"
952+
fn main() {
953+
if foo {
954+
955+
} else {
956+
957+
}$0 if bar {
958+
959+
}
960+
}
884961
"#,
885962
);
886963
}

0 commit comments

Comments
 (0)