diff options
-rw-r--r-- | crates/ide_assists/src/handlers/fill_match_arms.rs | 148 | ||||
-rw-r--r-- | crates/ide_assists/src/tests/generated.rs | 4 | ||||
-rw-r--r-- | crates/syntax/src/ast/edit_in_place.rs | 21 | ||||
-rw-r--r-- | xtask/src/tidy.rs | 1 |
4 files changed, 112 insertions, 62 deletions
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs index 97435f021..3d2cd739a 100644 --- a/crates/ide_assists/src/handlers/fill_match_arms.rs +++ b/crates/ide_assists/src/handlers/fill_match_arms.rs | |||
@@ -31,8 +31,8 @@ use crate::{ | |||
31 | // | 31 | // |
32 | // fn handle(action: Action) { | 32 | // fn handle(action: Action) { |
33 | // match action { | 33 | // match action { |
34 | // $0Action::Move { distance } => {} | 34 | // $0Action::Move { distance } => todo!(), |
35 | // Action::Stop => {} | 35 | // Action::Stop => todo!(), |
36 | // } | 36 | // } |
37 | // } | 37 | // } |
38 | // ``` | 38 | // ``` |
@@ -129,7 +129,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
129 | |builder| { | 129 | |builder| { |
130 | let new_match_arm_list = match_arm_list.clone_for_update(); | 130 | let new_match_arm_list = match_arm_list.clone_for_update(); |
131 | let missing_arms = missing_pats | 131 | let missing_arms = missing_pats |
132 | .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) | 132 | .map(|pat| make::match_arm(iter::once(pat), make::ext::expr_todo())) |
133 | .map(|it| it.clone_for_update()); | 133 | .map(|it| it.clone_for_update()); |
134 | 134 | ||
135 | let catch_all_arm = new_match_arm_list | 135 | let catch_all_arm = new_match_arm_list |
@@ -350,8 +350,8 @@ fn foo(a: bool) { | |||
350 | r#" | 350 | r#" |
351 | fn foo(a: bool) { | 351 | fn foo(a: bool) { |
352 | match a { | 352 | match a { |
353 | $0true => {} | 353 | $0true => todo!(), |
354 | false => {} | 354 | false => todo!(), |
355 | } | 355 | } |
356 | } | 356 | } |
357 | "#, | 357 | "#, |
@@ -373,7 +373,7 @@ fn foo(a: bool) { | |||
373 | fn foo(a: bool) { | 373 | fn foo(a: bool) { |
374 | match a { | 374 | match a { |
375 | true => {} | 375 | true => {} |
376 | $0false => {} | 376 | $0false => todo!(), |
377 | } | 377 | } |
378 | } | 378 | } |
379 | "#, | 379 | "#, |
@@ -410,10 +410,10 @@ fn foo(a: bool) { | |||
410 | r#" | 410 | r#" |
411 | fn foo(a: bool) { | 411 | fn foo(a: bool) { |
412 | match (a, a) { | 412 | match (a, a) { |
413 | $0(true, true) => {} | 413 | $0(true, true) => todo!(), |
414 | (true, false) => {} | 414 | (true, false) => todo!(), |
415 | (false, true) => {} | 415 | (false, true) => todo!(), |
416 | (false, false) => {} | 416 | (false, false) => todo!(), |
417 | } | 417 | } |
418 | } | 418 | } |
419 | "#, | 419 | "#, |
@@ -435,9 +435,9 @@ fn foo(a: bool) { | |||
435 | fn foo(a: bool) { | 435 | fn foo(a: bool) { |
436 | match (a, a) { | 436 | match (a, a) { |
437 | (false, true) => {} | 437 | (false, true) => {} |
438 | $0(true, true) => {} | 438 | $0(true, true) => todo!(), |
439 | (true, false) => {} | 439 | (true, false) => todo!(), |
440 | (false, false) => {} | 440 | (false, false) => todo!(), |
441 | } | 441 | } |
442 | } | 442 | } |
443 | "#, | 443 | "#, |
@@ -471,7 +471,7 @@ fn main() { | |||
471 | match A::As { | 471 | match A::As { |
472 | A::Bs { x, y: Some(_) } => {} | 472 | A::Bs { x, y: Some(_) } => {} |
473 | A::Cs(_, Some(_)) => {} | 473 | A::Cs(_, Some(_)) => {} |
474 | $0A::As => {} | 474 | $0A::As => todo!(), |
475 | } | 475 | } |
476 | } | 476 | } |
477 | "#, | 477 | "#, |
@@ -499,7 +499,7 @@ use Option::*; | |||
499 | fn main() { | 499 | fn main() { |
500 | match None { | 500 | match None { |
501 | None => {} | 501 | None => {} |
502 | Some(${0:_}) => {} | 502 | Some(${0:_}) => todo!(), |
503 | } | 503 | } |
504 | } | 504 | } |
505 | "#, | 505 | "#, |
@@ -523,7 +523,7 @@ enum A { As, Bs, Cs(Option<i32>) } | |||
523 | fn main() { | 523 | fn main() { |
524 | match A::As { | 524 | match A::As { |
525 | A::Cs(_) | A::Bs => {} | 525 | A::Cs(_) | A::Bs => {} |
526 | $0A::As => {} | 526 | $0A::As => todo!(), |
527 | } | 527 | } |
528 | } | 528 | } |
529 | "#, | 529 | "#, |
@@ -553,8 +553,8 @@ fn main() { | |||
553 | A::Bs if 0 < 1 => {} | 553 | A::Bs if 0 < 1 => {} |
554 | A::Ds(_value) => { let x = 1; } | 554 | A::Ds(_value) => { let x = 1; } |
555 | A::Es(B::Xs) => (), | 555 | A::Es(B::Xs) => (), |
556 | $0A::As => {} | 556 | $0A::As => todo!(), |
557 | A::Cs => {} | 557 | A::Cs => todo!(), |
558 | } | 558 | } |
559 | } | 559 | } |
560 | "#, | 560 | "#, |
@@ -580,7 +580,7 @@ fn main() { | |||
580 | match A::As { | 580 | match A::As { |
581 | A::As(_) => {} | 581 | A::As(_) => {} |
582 | a @ A::Bs(_) => {} | 582 | a @ A::Bs(_) => {} |
583 | A::Cs(${0:_}) => {} | 583 | A::Cs(${0:_}) => todo!(), |
584 | } | 584 | } |
585 | } | 585 | } |
586 | "#, | 586 | "#, |
@@ -605,11 +605,11 @@ enum A { As, Bs, Cs(String), Ds(String, String), Es { x: usize, y: usize } } | |||
605 | fn main() { | 605 | fn main() { |
606 | let a = A::As; | 606 | let a = A::As; |
607 | match a { | 607 | match a { |
608 | $0A::As => {} | 608 | $0A::As => todo!(), |
609 | A::Bs => {} | 609 | A::Bs => todo!(), |
610 | A::Cs(_) => {} | 610 | A::Cs(_) => todo!(), |
611 | A::Ds(_, _) => {} | 611 | A::Ds(_, _) => todo!(), |
612 | A::Es { x, y } => {} | 612 | A::Es { x, y } => todo!(), |
613 | } | 613 | } |
614 | } | 614 | } |
615 | "#, | 615 | "#, |
@@ -638,10 +638,10 @@ fn main() { | |||
638 | let a = A::One; | 638 | let a = A::One; |
639 | let b = B::One; | 639 | let b = B::One; |
640 | match (a, b) { | 640 | match (a, b) { |
641 | $0(A::One, B::One) => {} | 641 | $0(A::One, B::One) => todo!(), |
642 | (A::One, B::Two) => {} | 642 | (A::One, B::Two) => todo!(), |
643 | (A::Two, B::One) => {} | 643 | (A::Two, B::One) => todo!(), |
644 | (A::Two, B::Two) => {} | 644 | (A::Two, B::Two) => todo!(), |
645 | } | 645 | } |
646 | } | 646 | } |
647 | "#, | 647 | "#, |
@@ -670,10 +670,10 @@ fn main() { | |||
670 | let a = A::One; | 670 | let a = A::One; |
671 | let b = B::One; | 671 | let b = B::One; |
672 | match (&a, &b) { | 672 | match (&a, &b) { |
673 | $0(A::One, B::One) => {} | 673 | $0(A::One, B::One) => todo!(), |
674 | (A::One, B::Two) => {} | 674 | (A::One, B::Two) => todo!(), |
675 | (A::Two, B::One) => {} | 675 | (A::Two, B::One) => todo!(), |
676 | (A::Two, B::Two) => {} | 676 | (A::Two, B::Two) => todo!(), |
677 | } | 677 | } |
678 | } | 678 | } |
679 | "#, | 679 | "#, |
@@ -705,9 +705,9 @@ fn main() { | |||
705 | let b = B::One; | 705 | let b = B::One; |
706 | match (a, b) { | 706 | match (a, b) { |
707 | (A::Two, B::One) => {} | 707 | (A::Two, B::One) => {} |
708 | $0(A::One, B::One) => {} | 708 | $0(A::One, B::One) => todo!(), |
709 | (A::One, B::Two) => {} | 709 | (A::One, B::Two) => todo!(), |
710 | (A::Two, B::Two) => {} | 710 | (A::Two, B::Two) => todo!(), |
711 | } | 711 | } |
712 | } | 712 | } |
713 | "#, | 713 | "#, |
@@ -736,7 +736,7 @@ fn main() { | |||
736 | match (a, b) { | 736 | match (a, b) { |
737 | (Some(_), _) => {} | 737 | (Some(_), _) => {} |
738 | (None, Some(_)) => {} | 738 | (None, Some(_)) => {} |
739 | $0(None, None) => {} | 739 | $0(None, None) => todo!(), |
740 | } | 740 | } |
741 | } | 741 | } |
742 | "#, | 742 | "#, |
@@ -801,8 +801,8 @@ enum A { One, Two } | |||
801 | fn main() { | 801 | fn main() { |
802 | let a = A::One; | 802 | let a = A::One; |
803 | match (a, ) { | 803 | match (a, ) { |
804 | $0(A::One,) => {} | 804 | $0(A::One,) => todo!(), |
805 | (A::Two,) => {} | 805 | (A::Two,) => todo!(), |
806 | } | 806 | } |
807 | } | 807 | } |
808 | "#, | 808 | "#, |
@@ -826,7 +826,7 @@ enum A { As } | |||
826 | 826 | ||
827 | fn foo(a: &A) { | 827 | fn foo(a: &A) { |
828 | match a { | 828 | match a { |
829 | $0A::As => {} | 829 | $0A::As => todo!(), |
830 | } | 830 | } |
831 | } | 831 | } |
832 | "#, | 832 | "#, |
@@ -851,7 +851,7 @@ enum A { | |||
851 | 851 | ||
852 | fn foo(a: &mut A) { | 852 | fn foo(a: &mut A) { |
853 | match a { | 853 | match a { |
854 | $0A::Es { x, y } => {} | 854 | $0A::Es { x, y } => todo!(), |
855 | } | 855 | } |
856 | } | 856 | } |
857 | "#, | 857 | "#, |
@@ -891,8 +891,8 @@ enum E { X, Y } | |||
891 | 891 | ||
892 | fn main() { | 892 | fn main() { |
893 | match E::X { | 893 | match E::X { |
894 | $0E::X => {} | 894 | $0E::X => todo!(), |
895 | E::Y => {} | 895 | E::Y => todo!(), |
896 | } | 896 | } |
897 | } | 897 | } |
898 | "#, | 898 | "#, |
@@ -919,8 +919,8 @@ use foo::E::X; | |||
919 | 919 | ||
920 | fn main() { | 920 | fn main() { |
921 | match X { | 921 | match X { |
922 | $0X => {} | 922 | $0X => todo!(), |
923 | foo::E::Y => {} | 923 | foo::E::Y => todo!(), |
924 | } | 924 | } |
925 | } | 925 | } |
926 | "#, | 926 | "#, |
@@ -947,7 +947,7 @@ fn foo(a: A) { | |||
947 | match a { | 947 | match a { |
948 | // foo bar baz | 948 | // foo bar baz |
949 | A::One => {} | 949 | A::One => {} |
950 | $0A::Two => {} | 950 | $0A::Two => todo!(), |
951 | // This is where the rest should be | 951 | // This is where the rest should be |
952 | } | 952 | } |
953 | } | 953 | } |
@@ -971,8 +971,8 @@ fn foo(a: A) { | |||
971 | enum A { One, Two } | 971 | enum A { One, Two } |
972 | fn foo(a: A) { | 972 | fn foo(a: A) { |
973 | match a { | 973 | match a { |
974 | $0A::One => {} | 974 | $0A::One => todo!(), |
975 | A::Two => {} | 975 | A::Two => todo!(), |
976 | // foo bar baz | 976 | // foo bar baz |
977 | } | 977 | } |
978 | } | 978 | } |
@@ -996,8 +996,8 @@ fn foo(a: A) { | |||
996 | enum A { One, Two, } | 996 | enum A { One, Two, } |
997 | fn foo(a: A) { | 997 | fn foo(a: A) { |
998 | match a { | 998 | match a { |
999 | $0A::One => {} | 999 | $0A::One => todo!(), |
1000 | A::Two => {} | 1000 | A::Two => todo!(), |
1001 | } | 1001 | } |
1002 | } | 1002 | } |
1003 | "#, | 1003 | "#, |
@@ -1021,8 +1021,8 @@ fn foo(opt: Option<i32>) { | |||
1021 | r#" | 1021 | r#" |
1022 | fn foo(opt: Option<i32>) { | 1022 | fn foo(opt: Option<i32>) { |
1023 | match opt { | 1023 | match opt { |
1024 | Some(${0:_}) => {} | 1024 | Some(${0:_}) => todo!(), |
1025 | None => {} | 1025 | None => todo!(), |
1026 | } | 1026 | } |
1027 | } | 1027 | } |
1028 | "#, | 1028 | "#, |
@@ -1054,9 +1054,9 @@ enum Test { | |||
1054 | 1054 | ||
1055 | fn foo(t: Test) { | 1055 | fn foo(t: Test) { |
1056 | m!(match t { | 1056 | m!(match t { |
1057 | $0Test::A => {} | 1057 | $0Test::A => todo!(), |
1058 | Test::B => {} | 1058 | Test::B => todo!(), |
1059 | Test::C => {} | 1059 | Test::C => todo!(), |
1060 | }); | 1060 | }); |
1061 | }"#, | 1061 | }"#, |
1062 | ); | 1062 | ); |
@@ -1076,4 +1076,44 @@ fn foo(tuple: (A, A)) { | |||
1076 | "#, | 1076 | "#, |
1077 | ); | 1077 | ); |
1078 | } | 1078 | } |
1079 | |||
1080 | #[test] | ||
1081 | fn adds_comma_before_new_arms() { | ||
1082 | check_assist( | ||
1083 | fill_match_arms, | ||
1084 | r#" | ||
1085 | fn foo(t: bool) { | ||
1086 | match $0t { | ||
1087 | true => 1 + 2 | ||
1088 | } | ||
1089 | }"#, | ||
1090 | r#" | ||
1091 | fn foo(t: bool) { | ||
1092 | match t { | ||
1093 | true => 1 + 2, | ||
1094 | $0false => todo!(), | ||
1095 | } | ||
1096 | }"#, | ||
1097 | ); | ||
1098 | } | ||
1099 | |||
1100 | #[test] | ||
1101 | fn does_not_add_extra_comma() { | ||
1102 | check_assist( | ||
1103 | fill_match_arms, | ||
1104 | r#" | ||
1105 | fn foo(t: bool) { | ||
1106 | match $0t { | ||
1107 | true => 1 + 2, | ||
1108 | } | ||
1109 | }"#, | ||
1110 | r#" | ||
1111 | fn foo(t: bool) { | ||
1112 | match t { | ||
1113 | true => 1 + 2, | ||
1114 | $0false => todo!(), | ||
1115 | } | ||
1116 | }"#, | ||
1117 | ); | ||
1118 | } | ||
1079 | } | 1119 | } |
diff --git a/crates/ide_assists/src/tests/generated.rs b/crates/ide_assists/src/tests/generated.rs index 8a9b0777c..de5d9e55a 100644 --- a/crates/ide_assists/src/tests/generated.rs +++ b/crates/ide_assists/src/tests/generated.rs | |||
@@ -455,8 +455,8 @@ enum Action { Move { distance: u32 }, Stop } | |||
455 | 455 | ||
456 | fn handle(action: Action) { | 456 | fn handle(action: Action) { |
457 | match action { | 457 | match action { |
458 | $0Action::Move { distance } => {} | 458 | $0Action::Move { distance } => todo!(), |
459 | Action::Stop => {} | 459 | Action::Stop => todo!(), |
460 | } | 460 | } |
461 | } | 461 | } |
462 | "#####, | 462 | "#####, |
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs index ca8103668..f7ee29d14 100644 --- a/crates/syntax/src/ast/edit_in_place.rs +++ b/crates/syntax/src/ast/edit_in_place.rs | |||
@@ -356,13 +356,17 @@ impl ast::MatchArm { | |||
356 | impl ast::MatchArmList { | 356 | impl ast::MatchArmList { |
357 | pub fn add_arm(&self, arm: ast::MatchArm) { | 357 | pub fn add_arm(&self, arm: ast::MatchArm) { |
358 | normalize_ws_between_braces(self.syntax()); | 358 | normalize_ws_between_braces(self.syntax()); |
359 | let mut elements = Vec::new(); | ||
359 | let position = match self.arms().last() { | 360 | let position = match self.arms().last() { |
360 | Some(last_arm) => { | 361 | Some(last_arm) => { |
361 | let curly = last_arm | 362 | let comma = last_arm |
362 | .syntax() | 363 | .syntax() |
363 | .siblings_with_tokens(Direction::Next) | 364 | .siblings_with_tokens(Direction::Next) |
364 | .find(|it| it.kind() == T![,]); | 365 | .find(|it| it.kind() == T![,]); |
365 | Position::after(curly.unwrap_or_else(|| last_arm.syntax().clone().into())) | 366 | if needs_comma(&last_arm) && comma.is_none() { |
367 | elements.push(make::token(SyntaxKind::COMMA).into()); | ||
368 | } | ||
369 | Position::after(comma.unwrap_or_else(|| last_arm.syntax().clone().into())) | ||
366 | } | 370 | } |
367 | None => match self.l_curly_token() { | 371 | None => match self.l_curly_token() { |
368 | Some(it) => Position::after(it), | 372 | Some(it) => Position::after(it), |
@@ -370,11 +374,16 @@ impl ast::MatchArmList { | |||
370 | }, | 374 | }, |
371 | }; | 375 | }; |
372 | let indent = IndentLevel::from_node(self.syntax()) + 1; | 376 | let indent = IndentLevel::from_node(self.syntax()) + 1; |
373 | let elements = vec![ | 377 | elements.push(make::tokens::whitespace(&format!("\n{}", indent)).into()); |
374 | make::tokens::whitespace(&format!("\n{}", indent)).into(), | 378 | elements.push(arm.syntax().clone().into()); |
375 | arm.syntax().clone().into(), | 379 | if needs_comma(&arm) { |
376 | ]; | 380 | elements.push(make::token(SyntaxKind::COMMA).into()); |
381 | } | ||
377 | ted::insert_all(position, elements); | 382 | ted::insert_all(position, elements); |
383 | |||
384 | fn needs_comma(arm: &ast::MatchArm) -> bool { | ||
385 | arm.expr().map_or(false, |e| !e.is_block_like()) | ||
386 | } | ||
378 | } | 387 | } |
379 | } | 388 | } |
380 | 389 | ||
diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs index 82b33a7a0..6f687a788 100644 --- a/xtask/src/tidy.rs +++ b/xtask/src/tidy.rs | |||
@@ -275,6 +275,7 @@ fn check_todo(path: &Path, text: &str) { | |||
275 | // Some of our assists generate `todo!()`. | 275 | // Some of our assists generate `todo!()`. |
276 | "handlers/add_turbo_fish.rs", | 276 | "handlers/add_turbo_fish.rs", |
277 | "handlers/generate_function.rs", | 277 | "handlers/generate_function.rs", |
278 | "handlers/fill_match_arms.rs", | ||
278 | // To support generating `todo!()` in assists, we have `expr_todo()` in | 279 | // To support generating `todo!()` in assists, we have `expr_todo()` in |
279 | // `ast::make`. | 280 | // `ast::make`. |
280 | "ast/make.rs", | 281 | "ast/make.rs", |