aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers/extract_variable.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src/handlers/extract_variable.rs')
-rw-r--r--crates/ide_assists/src/handlers/extract_variable.rs223
1 files changed, 208 insertions, 15 deletions
diff --git a/crates/ide_assists/src/handlers/extract_variable.rs b/crates/ide_assists/src/handlers/extract_variable.rs
index 98f3dc6ca..7a32483dc 100644
--- a/crates/ide_assists/src/handlers/extract_variable.rs
+++ b/crates/ide_assists/src/handlers/extract_variable.rs
@@ -6,9 +6,8 @@ use syntax::{
6 }, 6 },
7 SyntaxNode, 7 SyntaxNode,
8}; 8};
9use test_utils::mark;
10 9
11use crate::{AssistContext, AssistId, AssistKind, Assists}; 10use crate::{utils::suggest_name, AssistContext, AssistId, AssistKind, Assists};
12 11
13// Assist: extract_variable 12// Assist: extract_variable
14// 13//
@@ -32,7 +31,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
32 } 31 }
33 let node = ctx.covering_element(); 32 let node = ctx.covering_element();
34 if node.kind() == COMMENT { 33 if node.kind() == COMMENT {
35 mark::hit!(extract_var_in_comment_is_not_applicable); 34 cov_mark::hit!(extract_var_in_comment_is_not_applicable);
36 return None; 35 return None;
37 } 36 }
38 let to_extract = node.ancestors().find_map(valid_target_expr)?; 37 let to_extract = node.ancestors().find_map(valid_target_expr)?;
@@ -54,7 +53,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
54 53
55 let var_name = match &field_shorthand { 54 let var_name = match &field_shorthand {
56 Some(it) => it.to_string(), 55 Some(it) => it.to_string(),
57 None => "var_name".to_string(), 56 None => suggest_name::variable(&to_extract, &ctx.sema),
58 }; 57 };
59 let expr_range = match &field_shorthand { 58 let expr_range = match &field_shorthand {
60 Some(it) => it.syntax().text_range().cover(to_extract.syntax().text_range()), 59 Some(it) => it.syntax().text_range().cover(to_extract.syntax().text_range()),
@@ -69,7 +68,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
69 format_to!(buf, "{}", to_extract.syntax()); 68 format_to!(buf, "{}", to_extract.syntax());
70 69
71 if let Anchor::Replace(stmt) = anchor { 70 if let Anchor::Replace(stmt) = anchor {
72 mark::hit!(test_extract_var_expr_stmt); 71 cov_mark::hit!(test_extract_var_expr_stmt);
73 if stmt.semicolon_token().is_none() { 72 if stmt.semicolon_token().is_none() {
74 buf.push_str(";"); 73 buf.push_str(";");
75 } 74 }
@@ -142,7 +141,7 @@ impl Anchor {
142 node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.tail_expr()) 141 node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.tail_expr())
143 { 142 {
144 if expr.syntax() == &node { 143 if expr.syntax() == &node {
145 mark::hit!(test_extract_var_last_expr); 144 cov_mark::hit!(test_extract_var_last_expr);
146 return Some(Anchor::Before(node)); 145 return Some(Anchor::Before(node));
147 } 146 }
148 } 147 }
@@ -175,8 +174,6 @@ impl Anchor {
175 174
176#[cfg(test)] 175#[cfg(test)]
177mod tests { 176mod tests {
178 use test_utils::mark;
179
180 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 177 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
181 178
182 use super::*; 179 use super::*;
@@ -199,13 +196,13 @@ fn foo() {
199 196
200 #[test] 197 #[test]
201 fn extract_var_in_comment_is_not_applicable() { 198 fn extract_var_in_comment_is_not_applicable() {
202 mark::check!(extract_var_in_comment_is_not_applicable); 199 cov_mark::check!(extract_var_in_comment_is_not_applicable);
203 check_assist_not_applicable(extract_variable, "fn main() { 1 + /* $0comment$0 */ 1; }"); 200 check_assist_not_applicable(extract_variable, "fn main() { 1 + /* $0comment$0 */ 1; }");
204 } 201 }
205 202
206 #[test] 203 #[test]
207 fn test_extract_var_expr_stmt() { 204 fn test_extract_var_expr_stmt() {
208 mark::check!(test_extract_var_expr_stmt); 205 cov_mark::check!(test_extract_var_expr_stmt);
209 check_assist( 206 check_assist(
210 extract_variable, 207 extract_variable,
211 r#" 208 r#"
@@ -250,7 +247,7 @@ fn foo() {
250 247
251 #[test] 248 #[test]
252 fn test_extract_var_last_expr() { 249 fn test_extract_var_last_expr() {
253 mark::check!(test_extract_var_last_expr); 250 cov_mark::check!(test_extract_var_last_expr);
254 check_assist( 251 check_assist(
255 extract_variable, 252 extract_variable,
256 r#" 253 r#"
@@ -274,8 +271,8 @@ fn foo() {
274"#, 271"#,
275 r#" 272 r#"
276fn foo() { 273fn foo() {
277 let $0var_name = bar(1 + 1); 274 let $0bar = bar(1 + 1);
278 var_name 275 bar
279} 276}
280"#, 277"#,
281 ) 278 )
@@ -401,8 +398,8 @@ fn main() {
401", 398",
402 " 399 "
403fn main() { 400fn main() {
404 let $0var_name = bar.foo(); 401 let $0foo = bar.foo();
405 let v = var_name; 402 let v = foo;
406} 403}
407", 404",
408 ); 405 );
@@ -557,6 +554,202 @@ fn main() {
557 } 554 }
558 555
559 #[test] 556 #[test]
557 fn extract_var_name_from_type() {
558 check_assist(
559 extract_variable,
560 r#"
561struct Test(i32);
562
563fn foo() -> Test {
564 $0{ Test(10) }$0
565}
566"#,
567 r#"
568struct Test(i32);
569
570fn foo() -> Test {
571 let $0test = { Test(10) };
572 test
573}
574"#,
575 )
576 }
577
578 #[test]
579 fn extract_var_name_from_parameter() {
580 check_assist(
581 extract_variable,
582 r#"
583fn bar(test: u32, size: u32)
584
585fn foo() {
586 bar(1, $01+1$0);
587}
588"#,
589 r#"
590fn bar(test: u32, size: u32)
591
592fn foo() {
593 let $0size = 1+1;
594 bar(1, size);
595}
596"#,
597 )
598 }
599
600 #[test]
601 fn extract_var_parameter_name_has_precedence_over_type() {
602 check_assist(
603 extract_variable,
604 r#"
605struct TextSize(u32);
606fn bar(test: u32, size: TextSize)
607
608fn foo() {
609 bar(1, $0{ TextSize(1+1) }$0);
610}
611"#,
612 r#"
613struct TextSize(u32);
614fn bar(test: u32, size: TextSize)
615
616fn foo() {
617 let $0size = { TextSize(1+1) };
618 bar(1, size);
619}
620"#,
621 )
622 }
623
624 #[test]
625 fn extract_var_name_from_function() {
626 check_assist(
627 extract_variable,
628 r#"
629fn is_required(test: u32, size: u32) -> bool
630
631fn foo() -> bool {
632 $0is_required(1, 2)$0
633}
634"#,
635 r#"
636fn is_required(test: u32, size: u32) -> bool
637
638fn foo() -> bool {
639 let $0is_required = is_required(1, 2);
640 is_required
641}
642"#,
643 )
644 }
645
646 #[test]
647 fn extract_var_name_from_method() {
648 check_assist(
649 extract_variable,
650 r#"
651struct S;
652impl S {
653 fn bar(&self, n: u32) -> u32 { n }
654}
655
656fn foo() -> u32 {
657 $0S.bar(1)$0
658}
659"#,
660 r#"
661struct S;
662impl S {
663 fn bar(&self, n: u32) -> u32 { n }
664}
665
666fn foo() -> u32 {
667 let $0bar = S.bar(1);
668 bar
669}
670"#,
671 )
672 }
673
674 #[test]
675 fn extract_var_name_from_method_param() {
676 check_assist(
677 extract_variable,
678 r#"
679struct S;
680impl S {
681 fn bar(&self, n: u32, size: u32) { n }
682}
683
684fn foo() {
685 S.bar($01 + 1$0, 2)
686}
687"#,
688 r#"
689struct S;
690impl S {
691 fn bar(&self, n: u32, size: u32) { n }
692}
693
694fn foo() {
695 let $0n = 1 + 1;
696 S.bar(n, 2)
697}
698"#,
699 )
700 }
701
702 #[test]
703 fn extract_var_name_from_ufcs_method_param() {
704 check_assist(
705 extract_variable,
706 r#"
707struct S;
708impl S {
709 fn bar(&self, n: u32, size: u32) { n }
710}
711
712fn foo() {
713 S::bar(&S, $01 + 1$0, 2)
714}
715"#,
716 r#"
717struct S;
718impl S {
719 fn bar(&self, n: u32, size: u32) { n }
720}
721
722fn foo() {
723 let $0n = 1 + 1;
724 S::bar(&S, n, 2)
725}
726"#,
727 )
728 }
729
730 #[test]
731 fn extract_var_parameter_name_has_precedence_over_function() {
732 check_assist(
733 extract_variable,
734 r#"
735fn bar(test: u32, size: u32)
736
737fn foo() {
738 bar(1, $0symbol_size(1, 2)$0);
739}
740"#,
741 r#"
742fn bar(test: u32, size: u32)
743
744fn foo() {
745 let $0size = symbol_size(1, 2);
746 bar(1, size);
747}
748"#,
749 )
750 }
751
752 #[test]
560 fn test_extract_var_for_return_not_applicable() { 753 fn test_extract_var_for_return_not_applicable() {
561 check_assist_not_applicable(extract_variable, "fn foo() { $0return$0; } "); 754 check_assist_not_applicable(extract_variable, "fn foo() { $0return$0; } ");
562 } 755 }