diff --git a/crates/ra_assists/src/handlers/inline_local_variable.rs b/crates/ra_assists/src/handlers/inline_local_variable.rs index 53a72309b1..eb5112343c 100644 --- a/crates/ra_assists/src/handlers/inline_local_variable.rs +++ b/crates/ra_assists/src/handlers/inline_local_variable.rs @@ -2,9 +2,9 @@ use ra_syntax::{ ast::{self, AstNode, AstToken}, TextRange, }; +use test_utils::tested_by; -use crate::assist_ctx::ActionBuilder; -use crate::{Assist, AssistCtx, AssistId}; +use crate::{assist_ctx::ActionBuilder, Assist, AssistCtx, AssistId}; // Assist: inline_local_variable // @@ -29,6 +29,11 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option { _ => return None, }; if bind_pat.is_mutable() { + tested_by!(test_not_inline_mut_variable); + return None; + } + if !bind_pat.syntax().text_range().contains_inclusive(ctx.frange.range.start()) { + tested_by!(not_applicable_outside_of_bind_pat); return None; } let initializer_expr = let_stmt.initializer()?; @@ -111,6 +116,8 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option { #[cfg(test)] mod tests { + use test_utils::covers; + use crate::helpers::{check_assist, check_assist_not_applicable}; use super::*; @@ -119,7 +126,7 @@ mod tests { fn test_inline_let_bind_literal_expr() { check_assist( inline_local_variable, - " + r" fn bar(a: usize) {} fn foo() { let a<|> = 1; @@ -133,7 +140,7 @@ fn foo() { let b = a * 10; bar(a); }", - " + r" fn bar(a: usize) {} fn foo() { <|>1 + 1; @@ -153,7 +160,7 @@ fn foo() { fn test_inline_let_bind_bin_expr() { check_assist( inline_local_variable, - " + r" fn bar(a: usize) {} fn foo() { let a<|> = 1 + 1; @@ -167,7 +174,7 @@ fn foo() { let b = a * 10; bar(a); }", - " + r" fn bar(a: usize) {} fn foo() { <|>(1 + 1) + 1; @@ -187,7 +194,7 @@ fn foo() { fn test_inline_let_bind_function_call_expr() { check_assist( inline_local_variable, - " + r" fn bar(a: usize) {} fn foo() { let a<|> = bar(1); @@ -201,7 +208,7 @@ fn foo() { let b = a * 10; bar(a); }", - " + r" fn bar(a: usize) {} fn foo() { <|>bar(1) + 1; @@ -221,7 +228,7 @@ fn foo() { fn test_inline_let_bind_cast_expr() { check_assist( inline_local_variable, - " + r" fn bar(a: usize): usize { a } fn foo() { let a<|> = bar(1) as u64; @@ -235,7 +242,7 @@ fn foo() { let b = a * 10; bar(a); }", - " + r" fn bar(a: usize): usize { a } fn foo() { <|>(bar(1) as u64) + 1; @@ -255,7 +262,7 @@ fn foo() { fn test_inline_let_bind_block_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = { 10 + 1 }; a + 1; @@ -268,7 +275,7 @@ fn foo() { let b = a * 10; bar(a); }", - " + r" fn foo() { <|>{ 10 + 1 } + 1; if { 10 + 1 } > 10 { @@ -287,7 +294,7 @@ fn foo() { fn test_inline_let_bind_paren_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = ( 10 + 1 ); a + 1; @@ -300,7 +307,7 @@ fn foo() { let b = a * 10; bar(a); }", - " + r" fn foo() { <|>( 10 + 1 ) + 1; if ( 10 + 1 ) > 10 { @@ -317,9 +324,10 @@ fn foo() { #[test] fn test_not_inline_mut_variable() { + covers!(test_not_inline_mut_variable); check_assist_not_applicable( inline_local_variable, - " + r" fn foo() { let mut a<|> = 1 + 1; a + 1; @@ -331,13 +339,13 @@ fn foo() { fn test_call_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = bar(10 + 1); let b = a * 10; let c = a as usize; }", - " + r" fn foo() { <|>let b = bar(10 + 1) * 10; let c = bar(10 + 1) as usize; @@ -349,14 +357,14 @@ fn foo() { fn test_index_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let x = vec![1, 2, 3]; let a<|> = x[0]; let b = a * 10; let c = a as usize; }", - " + r" fn foo() { let x = vec![1, 2, 3]; <|>let b = x[0] * 10; @@ -369,14 +377,14 @@ fn foo() { fn test_method_call_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let bar = vec![1]; let a<|> = bar.len(); let b = a * 10; let c = a as usize; }", - " + r" fn foo() { let bar = vec![1]; <|>let b = bar.len() * 10; @@ -389,7 +397,7 @@ fn foo() { fn test_field_expr() { check_assist( inline_local_variable, - " + r" struct Bar { foo: usize } @@ -400,7 +408,7 @@ fn foo() { let b = a * 10; let c = a as usize; }", - " + r" struct Bar { foo: usize } @@ -417,7 +425,7 @@ fn foo() { fn test_try_expr() { check_assist( inline_local_variable, - " + r" fn foo() -> Option { let bar = Some(1); let a<|> = bar?; @@ -425,7 +433,7 @@ fn foo() -> Option { let c = a as usize; None }", - " + r" fn foo() -> Option { let bar = Some(1); <|>let b = bar? * 10; @@ -439,13 +447,13 @@ fn foo() -> Option { fn test_ref_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let bar = 10; let a<|> = &bar; let b = a * 10; }", - " + r" fn foo() { let bar = 10; <|>let b = &bar * 10; @@ -457,12 +465,12 @@ fn foo() { fn test_tuple_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = (10, 20); let b = a[0]; }", - " + r" fn foo() { <|>let b = (10, 20)[0]; }", @@ -473,12 +481,12 @@ fn foo() { fn test_array_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = [1, 2, 3]; let b = a.len(); }", - " + r" fn foo() { <|>let b = [1, 2, 3].len(); }", @@ -489,13 +497,13 @@ fn foo() { fn test_paren() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = (10 + 20); let b = a * 10; let c = a as usize; }", - " + r" fn foo() { <|>let b = (10 + 20) * 10; let c = (10 + 20) as usize; @@ -507,14 +515,14 @@ fn foo() { fn test_path_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let d = 10; let a<|> = d; let b = a * 10; let c = a as usize; }", - " + r" fn foo() { let d = 10; <|>let b = d * 10; @@ -527,13 +535,13 @@ fn foo() { fn test_block_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = { 10 }; let b = a * 10; let c = a as usize; }", - " + r" fn foo() { <|>let b = { 10 } * 10; let c = { 10 } as usize; @@ -545,7 +553,7 @@ fn foo() { fn test_used_in_different_expr1() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = 10 + 20; let b = a * 10; @@ -553,7 +561,7 @@ fn foo() { let d = [a, 10]; let e = (a); }", - " + r" fn foo() { <|>let b = (10 + 20) * 10; let c = (10 + 20, 20); @@ -567,12 +575,12 @@ fn foo() { fn test_used_in_for_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = vec![10, 20]; for i in a {} }", - " + r" fn foo() { <|>for i in vec![10, 20] {} }", @@ -583,12 +591,12 @@ fn foo() { fn test_used_in_while_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = 1 > 0; while a {} }", - " + r" fn foo() { <|>while 1 > 0 {} }", @@ -599,14 +607,14 @@ fn foo() { fn test_used_in_break_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = 1 + 1; loop { break a; } }", - " + r" fn foo() { <|>loop { break 1 + 1; @@ -619,12 +627,12 @@ fn foo() { fn test_used_in_return_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = 1 > 0; return a; }", - " + r" fn foo() { <|>return 1 > 0; }", @@ -635,12 +643,12 @@ fn foo() { fn test_used_in_match_expr() { check_assist( inline_local_variable, - " + r" fn foo() { let a<|> = 1 > 0; match a {} }", - " + r" fn foo() { <|>match 1 > 0 {} }", @@ -651,11 +659,25 @@ fn foo() { fn test_not_applicable_if_variable_unused() { check_assist_not_applicable( inline_local_variable, - " + r" fn foo() { let <|>a = 0; } ", ) } + + #[test] + fn not_applicable_outside_of_bind_pat() { + covers!(not_applicable_outside_of_bind_pat); + check_assist_not_applicable( + inline_local_variable, + r" +fn main() { + let x = <|>1 + 2; + x * 4; +} +", + ) + } } diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index deeada2de5..50a15f9786 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs @@ -178,19 +178,23 @@ mod helpers { (db, file_id) } - pub(crate) fn check_assist(assist: AssistHandler, before: &str, after: &str) { - check(assist, before, ExpectedResult::After(after)); + pub(crate) fn check_assist( + assist: AssistHandler, + ra_fixture_before: &str, + ra_fixture_after: &str, + ) { + check(assist, ra_fixture_before, ExpectedResult::After(ra_fixture_after)); } // FIXME: instead of having a separate function here, maybe use // `extract_ranges` and mark the target as ` ` in the // fixuture? - pub(crate) fn check_assist_target(assist: AssistHandler, before: &str, target: &str) { - check(assist, before, ExpectedResult::Target(target)); + pub(crate) fn check_assist_target(assist: AssistHandler, ra_fixture: &str, target: &str) { + check(assist, ra_fixture, ExpectedResult::Target(target)); } - pub(crate) fn check_assist_not_applicable(assist: AssistHandler, before: &str) { - check(assist, before, ExpectedResult::NotApplicable); + pub(crate) fn check_assist_not_applicable(assist: AssistHandler, ra_fixture: &str) { + check(assist, ra_fixture, ExpectedResult::NotApplicable); } enum ExpectedResult<'a> { diff --git a/crates/ra_assists/src/marks.rs b/crates/ra_assists/src/marks.rs index c20e4db9e9..cef3df4e5a 100644 --- a/crates/ra_assists/src/marks.rs +++ b/crates/ra_assists/src/marks.rs @@ -4,4 +4,6 @@ test_utils::marks!( introduce_var_in_comment_is_not_applicable test_introduce_var_expr_stmt test_introduce_var_last_expr + not_applicable_outside_of_bind_pat + test_not_inline_mut_variable ); diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 979a3f7a04..7e41db5301 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -320,7 +320,7 @@ fn highlight_injection( let call_info = call_info_for_token(&sema, expanded)?; let idx = call_info.active_parameter?; let name = call_info.signature.parameter_names.get(idx)?; - if name != "ra_fixture" { + if !name.starts_with("ra_fixture") { return None; } let value = literal.value()?;