aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api_light/src/join_lines.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api_light/src/join_lines.rs')
-rw-r--r--crates/ra_ide_api_light/src/join_lines.rs137
1 files changed, 134 insertions, 3 deletions
diff --git a/crates/ra_ide_api_light/src/join_lines.rs b/crates/ra_ide_api_light/src/join_lines.rs
index 949ee1544..b5bcd62fb 100644
--- a/crates/ra_ide_api_light/src/join_lines.rs
+++ b/crates/ra_ide_api_light/src/join_lines.rs
@@ -2,8 +2,9 @@ use itertools::Itertools;
2use ra_syntax::{ 2use ra_syntax::{
3 SourceFile, TextRange, TextUnit, AstNode, SyntaxNode, 3 SourceFile, TextRange, TextUnit, AstNode, SyntaxNode,
4 SyntaxKind::{self, WHITESPACE, COMMA, R_CURLY, R_PAREN, R_BRACK}, 4 SyntaxKind::{self, WHITESPACE, COMMA, R_CURLY, R_PAREN, R_BRACK},
5 algo::find_covering_node, 5 algo::{find_covering_node, non_trivia_sibling},
6 ast, 6 ast,
7 Direction,
7}; 8};
8use ra_fmt::{ 9use ra_fmt::{
9 compute_ws, extract_trivial_expression 10 compute_ws, extract_trivial_expression
@@ -120,11 +121,30 @@ fn remove_newline(
120 } 121 }
121} 122}
122 123
124fn has_comma_after(node: &SyntaxNode) -> bool {
125 match non_trivia_sibling(node, Direction::Next) {
126 Some(n) => n.kind() == COMMA,
127 _ => false,
128 }
129}
130
123fn join_single_expr_block(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> { 131fn join_single_expr_block(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> {
124 let block = ast::Block::cast(node.parent()?)?; 132 let block = ast::Block::cast(node.parent()?)?;
125 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; 133 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
126 let expr = extract_trivial_expression(block)?; 134 let expr = extract_trivial_expression(block)?;
127 edit.replace(block_expr.syntax().range(), expr.syntax().text().to_string()); 135
136 let block_range = block_expr.syntax().range();
137 let mut buf = expr.syntax().text().to_string();
138
139 // Match block needs to have a comma after the block
140 if let Some(match_arm) = block_expr.syntax().parent().and_then(ast::MatchArm::cast) {
141 if !has_comma_after(match_arm.syntax()) {
142 buf.push(',');
143 }
144 }
145
146 edit.replace(block_range, buf);
147
128 Some(()) 148 Some(())
129} 149}
130 150
@@ -208,7 +228,6 @@ fn foo() {
208 } 228 }
209 229
210 #[test] 230 #[test]
211 #[ignore] // FIXME: https://github.com/rust-analyzer/rust-analyzer/issues/868
212 fn join_lines_adds_comma_for_block_in_match_arm() { 231 fn join_lines_adds_comma_for_block_in_match_arm() {
213 check_join_lines( 232 check_join_lines(
214 r" 233 r"
@@ -231,6 +250,118 @@ fn foo(e: Result<U, V>) {
231 } 250 }
232 251
233 #[test] 252 #[test]
253 fn join_lines_keeps_comma_for_block_in_match_arm() {
254 // We already have a comma
255 check_join_lines(
256 r"
257fn foo(e: Result<U, V>) {
258 match e {
259 Ok(u) => <|>{
260 u.foo()
261 },
262 Err(v) => v,
263 }
264}",
265 r"
266fn foo(e: Result<U, V>) {
267 match e {
268 Ok(u) => <|>u.foo(),
269 Err(v) => v,
270 }
271}",
272 );
273
274 // comma with whitespace between brace and ,
275 check_join_lines(
276 r"
277fn foo(e: Result<U, V>) {
278 match e {
279 Ok(u) => <|>{
280 u.foo()
281 } ,
282 Err(v) => v,
283 }
284}",
285 r"
286fn foo(e: Result<U, V>) {
287 match e {
288 Ok(u) => <|>u.foo() ,
289 Err(v) => v,
290 }
291}",
292 );
293
294 // comma with newline between brace and ,
295 check_join_lines(
296 r"
297fn foo(e: Result<U, V>) {
298 match e {
299 Ok(u) => <|>{
300 u.foo()
301 }
302 ,
303 Err(v) => v,
304 }
305}",
306 r"
307fn foo(e: Result<U, V>) {
308 match e {
309 Ok(u) => <|>u.foo()
310 ,
311 Err(v) => v,
312 }
313}",
314 );
315 }
316
317 #[test]
318 fn join_lines_keeps_comma_with_single_arg_tuple() {
319 // A single arg tuple
320 check_join_lines(
321 r"
322fn foo() {
323 let x = (<|>{
324 4
325 },);
326}",
327 r"
328fn foo() {
329 let x = (<|>4,);
330}",
331 );
332
333 // single arg tuple with whitespace between brace and comma
334 check_join_lines(
335 r"
336fn foo() {
337 let x = (<|>{
338 4
339 } ,);
340}",
341 r"
342fn foo() {
343 let x = (<|>4 ,);
344}",
345 );
346
347 // single arg tuple with newline between brace and comma
348 check_join_lines(
349 r"
350fn foo() {
351 let x = (<|>{
352 4
353 }
354 ,);
355}",
356 r"
357fn foo() {
358 let x = (<|>4
359 ,);
360}",
361 );
362 }
363
364 #[test]
234 fn test_join_lines_use_items_left() { 365 fn test_join_lines_use_items_left() {
235 // No space after the '{' 366 // No space after the '{'
236 check_join_lines( 367 check_join_lines(