aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/inline_local_variable.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers/inline_local_variable.rs')
-rw-r--r--crates/ra_assists/src/handlers/inline_local_variable.rs95
1 files changed, 47 insertions, 48 deletions
diff --git a/crates/ra_assists/src/handlers/inline_local_variable.rs b/crates/ra_assists/src/handlers/inline_local_variable.rs
index f5702f6e0..d26e68847 100644
--- a/crates/ra_assists/src/handlers/inline_local_variable.rs
+++ b/crates/ra_assists/src/handlers/inline_local_variable.rs
@@ -3,9 +3,12 @@ use ra_syntax::{
3 ast::{self, AstNode, AstToken}, 3 ast::{self, AstNode, AstToken},
4 TextRange, 4 TextRange,
5}; 5};
6use test_utils::tested_by; 6use test_utils::mark;
7 7
8use crate::{assist_ctx::ActionBuilder, Assist, AssistCtx, AssistId}; 8use crate::{
9 assist_context::{AssistContext, Assists},
10 AssistId,
11};
9 12
10// Assist: inline_local_variable 13// Assist: inline_local_variable
11// 14//
@@ -23,18 +26,18 @@ use crate::{assist_ctx::ActionBuilder, Assist, AssistCtx, AssistId};
23// (1 + 2) * 4; 26// (1 + 2) * 4;
24// } 27// }
25// ``` 28// ```
26pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option<Assist> { 29pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
27 let let_stmt = ctx.find_node_at_offset::<ast::LetStmt>()?; 30 let let_stmt = ctx.find_node_at_offset::<ast::LetStmt>()?;
28 let bind_pat = match let_stmt.pat()? { 31 let bind_pat = match let_stmt.pat()? {
29 ast::Pat::BindPat(pat) => pat, 32 ast::Pat::BindPat(pat) => pat,
30 _ => return None, 33 _ => return None,
31 }; 34 };
32 if bind_pat.mut_token().is_some() { 35 if bind_pat.mut_token().is_some() {
33 tested_by!(test_not_inline_mut_variable); 36 mark::hit!(test_not_inline_mut_variable);
34 return None; 37 return None;
35 } 38 }
36 if !bind_pat.syntax().text_range().contains_inclusive(ctx.frange.range.start()) { 39 if !bind_pat.syntax().text_range().contains_inclusive(ctx.offset()) {
37 tested_by!(not_applicable_outside_of_bind_pat); 40 mark::hit!(not_applicable_outside_of_bind_pat);
38 return None; 41 return None;
39 } 42 }
40 let initializer_expr = let_stmt.initializer()?; 43 let initializer_expr = let_stmt.initializer()?;
@@ -43,7 +46,7 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option<Assist> {
43 let def = Definition::Local(def); 46 let def = Definition::Local(def);
44 let refs = def.find_usages(ctx.db, None); 47 let refs = def.find_usages(ctx.db, None);
45 if refs.is_empty() { 48 if refs.is_empty() {
46 tested_by!(test_not_applicable_if_variable_unused); 49 mark::hit!(test_not_applicable_if_variable_unused);
47 return None; 50 return None;
48 }; 51 };
49 52
@@ -89,6 +92,7 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option<Assist> {
89 | (ast::Expr::ParenExpr(_), _) 92 | (ast::Expr::ParenExpr(_), _)
90 | (ast::Expr::PathExpr(_), _) 93 | (ast::Expr::PathExpr(_), _)
91 | (ast::Expr::BlockExpr(_), _) 94 | (ast::Expr::BlockExpr(_), _)
95 | (ast::Expr::EffectExpr(_), _)
92 | (_, ast::Expr::CallExpr(_)) 96 | (_, ast::Expr::CallExpr(_))
93 | (_, ast::Expr::TupleExpr(_)) 97 | (_, ast::Expr::TupleExpr(_))
94 | (_, ast::Expr::ArrayExpr(_)) 98 | (_, ast::Expr::ArrayExpr(_))
@@ -105,26 +109,21 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option<Assist> {
105 let init_str = initializer_expr.syntax().text().to_string(); 109 let init_str = initializer_expr.syntax().text().to_string();
106 let init_in_paren = format!("({})", &init_str); 110 let init_in_paren = format!("({})", &init_str);
107 111
108 ctx.add_assist( 112 let target = bind_pat.syntax().text_range();
109 AssistId("inline_local_variable"), 113 acc.add(AssistId("inline_local_variable"), "Inline variable", target, move |builder| {
110 "Inline variable", 114 builder.delete(delete_range);
111 move |edit: &mut ActionBuilder| { 115 for (desc, should_wrap) in refs.iter().zip(wrap_in_parens) {
112 edit.delete(delete_range); 116 let replacement = if should_wrap { init_in_paren.clone() } else { init_str.clone() };
113 for (desc, should_wrap) in refs.iter().zip(wrap_in_parens) { 117 builder.replace(desc.file_range.range, replacement)
114 let replacement = 118 }
115 if should_wrap { init_in_paren.clone() } else { init_str.clone() }; 119 })
116 edit.replace(desc.file_range.range, replacement)
117 }
118 edit.set_cursor(delete_range.start())
119 },
120 )
121} 120}
122 121
123#[cfg(test)] 122#[cfg(test)]
124mod tests { 123mod tests {
125 use test_utils::covers; 124 use test_utils::mark;
126 125
127 use crate::helpers::{check_assist, check_assist_not_applicable}; 126 use crate::tests::{check_assist, check_assist_not_applicable};
128 127
129 use super::*; 128 use super::*;
130 129
@@ -149,7 +148,7 @@ fn foo() {
149 r" 148 r"
150fn bar(a: usize) {} 149fn bar(a: usize) {}
151fn foo() { 150fn foo() {
152 <|>1 + 1; 151 1 + 1;
153 if 1 > 10 { 152 if 1 > 10 {
154 } 153 }
155 154
@@ -183,7 +182,7 @@ fn foo() {
183 r" 182 r"
184fn bar(a: usize) {} 183fn bar(a: usize) {}
185fn foo() { 184fn foo() {
186 <|>(1 + 1) + 1; 185 (1 + 1) + 1;
187 if (1 + 1) > 10 { 186 if (1 + 1) > 10 {
188 } 187 }
189 188
@@ -217,7 +216,7 @@ fn foo() {
217 r" 216 r"
218fn bar(a: usize) {} 217fn bar(a: usize) {}
219fn foo() { 218fn foo() {
220 <|>bar(1) + 1; 219 bar(1) + 1;
221 if bar(1) > 10 { 220 if bar(1) > 10 {
222 } 221 }
223 222
@@ -251,7 +250,7 @@ fn foo() {
251 r" 250 r"
252fn bar(a: usize): usize { a } 251fn bar(a: usize): usize { a }
253fn foo() { 252fn foo() {
254 <|>(bar(1) as u64) + 1; 253 (bar(1) as u64) + 1;
255 if (bar(1) as u64) > 10 { 254 if (bar(1) as u64) > 10 {
256 } 255 }
257 256
@@ -283,7 +282,7 @@ fn foo() {
283}", 282}",
284 r" 283 r"
285fn foo() { 284fn foo() {
286 <|>{ 10 + 1 } + 1; 285 { 10 + 1 } + 1;
287 if { 10 + 1 } > 10 { 286 if { 10 + 1 } > 10 {
288 } 287 }
289 288
@@ -315,7 +314,7 @@ fn foo() {
315}", 314}",
316 r" 315 r"
317fn foo() { 316fn foo() {
318 <|>( 10 + 1 ) + 1; 317 ( 10 + 1 ) + 1;
319 if ( 10 + 1 ) > 10 { 318 if ( 10 + 1 ) > 10 {
320 } 319 }
321 320
@@ -330,7 +329,7 @@ fn foo() {
330 329
331 #[test] 330 #[test]
332 fn test_not_inline_mut_variable() { 331 fn test_not_inline_mut_variable() {
333 covers!(test_not_inline_mut_variable); 332 mark::check!(test_not_inline_mut_variable);
334 check_assist_not_applicable( 333 check_assist_not_applicable(
335 inline_local_variable, 334 inline_local_variable,
336 r" 335 r"
@@ -353,7 +352,7 @@ fn foo() {
353}", 352}",
354 r" 353 r"
355fn foo() { 354fn foo() {
356 <|>let b = bar(10 + 1) * 10; 355 let b = bar(10 + 1) * 10;
357 let c = bar(10 + 1) as usize; 356 let c = bar(10 + 1) as usize;
358}", 357}",
359 ); 358 );
@@ -373,7 +372,7 @@ fn foo() {
373 r" 372 r"
374fn foo() { 373fn foo() {
375 let x = vec![1, 2, 3]; 374 let x = vec![1, 2, 3];
376 <|>let b = x[0] * 10; 375 let b = x[0] * 10;
377 let c = x[0] as usize; 376 let c = x[0] as usize;
378}", 377}",
379 ); 378 );
@@ -393,7 +392,7 @@ fn foo() {
393 r" 392 r"
394fn foo() { 393fn foo() {
395 let bar = vec![1]; 394 let bar = vec![1];
396 <|>let b = bar.len() * 10; 395 let b = bar.len() * 10;
397 let c = bar.len() as usize; 396 let c = bar.len() as usize;
398}", 397}",
399 ); 398 );
@@ -421,7 +420,7 @@ struct Bar {
421 420
422fn foo() { 421fn foo() {
423 let bar = Bar { foo: 1 }; 422 let bar = Bar { foo: 1 };
424 <|>let b = bar.foo * 10; 423 let b = bar.foo * 10;
425 let c = bar.foo as usize; 424 let c = bar.foo as usize;
426}", 425}",
427 ); 426 );
@@ -442,7 +441,7 @@ fn foo() -> Option<usize> {
442 r" 441 r"
443fn foo() -> Option<usize> { 442fn foo() -> Option<usize> {
444 let bar = Some(1); 443 let bar = Some(1);
445 <|>let b = bar? * 10; 444 let b = bar? * 10;
446 let c = bar? as usize; 445 let c = bar? as usize;
447 None 446 None
448}", 447}",
@@ -462,7 +461,7 @@ fn foo() {
462 r" 461 r"
463fn foo() { 462fn foo() {
464 let bar = 10; 463 let bar = 10;
465 <|>let b = &bar * 10; 464 let b = &bar * 10;
466}", 465}",
467 ); 466 );
468 } 467 }
@@ -478,7 +477,7 @@ fn foo() {
478}", 477}",
479 r" 478 r"
480fn foo() { 479fn foo() {
481 <|>let b = (10, 20)[0]; 480 let b = (10, 20)[0];
482}", 481}",
483 ); 482 );
484 } 483 }
@@ -494,7 +493,7 @@ fn foo() {
494}", 493}",
495 r" 494 r"
496fn foo() { 495fn foo() {
497 <|>let b = [1, 2, 3].len(); 496 let b = [1, 2, 3].len();
498}", 497}",
499 ); 498 );
500 } 499 }
@@ -511,7 +510,7 @@ fn foo() {
511}", 510}",
512 r" 511 r"
513fn foo() { 512fn foo() {
514 <|>let b = (10 + 20) * 10; 513 let b = (10 + 20) * 10;
515 let c = (10 + 20) as usize; 514 let c = (10 + 20) as usize;
516}", 515}",
517 ); 516 );
@@ -531,7 +530,7 @@ fn foo() {
531 r" 530 r"
532fn foo() { 531fn foo() {
533 let d = 10; 532 let d = 10;
534 <|>let b = d * 10; 533 let b = d * 10;
535 let c = d as usize; 534 let c = d as usize;
536}", 535}",
537 ); 536 );
@@ -549,7 +548,7 @@ fn foo() {
549}", 548}",
550 r" 549 r"
551fn foo() { 550fn foo() {
552 <|>let b = { 10 } * 10; 551 let b = { 10 } * 10;
553 let c = { 10 } as usize; 552 let c = { 10 } as usize;
554}", 553}",
555 ); 554 );
@@ -569,7 +568,7 @@ fn foo() {
569}", 568}",
570 r" 569 r"
571fn foo() { 570fn foo() {
572 <|>let b = (10 + 20) * 10; 571 let b = (10 + 20) * 10;
573 let c = (10 + 20, 20); 572 let c = (10 + 20, 20);
574 let d = [10 + 20, 10]; 573 let d = [10 + 20, 10];
575 let e = (10 + 20); 574 let e = (10 + 20);
@@ -588,7 +587,7 @@ fn foo() {
588}", 587}",
589 r" 588 r"
590fn foo() { 589fn foo() {
591 <|>for i in vec![10, 20] {} 590 for i in vec![10, 20] {}
592}", 591}",
593 ); 592 );
594 } 593 }
@@ -604,7 +603,7 @@ fn foo() {
604}", 603}",
605 r" 604 r"
606fn foo() { 605fn foo() {
607 <|>while 1 > 0 {} 606 while 1 > 0 {}
608}", 607}",
609 ); 608 );
610 } 609 }
@@ -622,7 +621,7 @@ fn foo() {
622}", 621}",
623 r" 622 r"
624fn foo() { 623fn foo() {
625 <|>loop { 624 loop {
626 break 1 + 1; 625 break 1 + 1;
627 } 626 }
628}", 627}",
@@ -640,7 +639,7 @@ fn foo() {
640}", 639}",
641 r" 640 r"
642fn foo() { 641fn foo() {
643 <|>return 1 > 0; 642 return 1 > 0;
644}", 643}",
645 ); 644 );
646 } 645 }
@@ -656,14 +655,14 @@ fn foo() {
656}", 655}",
657 r" 656 r"
658fn foo() { 657fn foo() {
659 <|>match 1 > 0 {} 658 match 1 > 0 {}
660}", 659}",
661 ); 660 );
662 } 661 }
663 662
664 #[test] 663 #[test]
665 fn test_not_applicable_if_variable_unused() { 664 fn test_not_applicable_if_variable_unused() {
666 covers!(test_not_applicable_if_variable_unused); 665 mark::check!(test_not_applicable_if_variable_unused);
667 check_assist_not_applicable( 666 check_assist_not_applicable(
668 inline_local_variable, 667 inline_local_variable,
669 r" 668 r"
@@ -676,7 +675,7 @@ fn foo() {
676 675
677 #[test] 676 #[test]
678 fn not_applicable_outside_of_bind_pat() { 677 fn not_applicable_outside_of_bind_pat() {
679 covers!(not_applicable_outside_of_bind_pat); 678 mark::check!(not_applicable_outside_of_bind_pat);
680 check_assist_not_applicable( 679 check_assist_not_applicable(
681 inline_local_variable, 680 inline_local_variable,
682 r" 681 r"