Unnamed repository; edit this file 'description' to name the repository.
support ref params as well
| -rw-r--r-- | crates/ide_assists/src/handlers/extract_variable.rs | 113 |
1 files changed, 109 insertions, 4 deletions
diff --git a/crates/ide_assists/src/handlers/extract_variable.rs b/crates/ide_assists/src/handlers/extract_variable.rs index d7a8e1dd4c..fb48c0b4f1 100644 --- a/crates/ide_assists/src/handlers/extract_variable.rs +++ b/crates/ide_assists/src/handlers/extract_variable.rs @@ -52,10 +52,10 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option } } - let is_mutable_reference = if let Some(receiver_type) = get_receiver_type(&ctx, &to_extract) { - receiver_type.is_mutable_reference() + let ref_kind: RefKind = if let Some(receiver_type) = get_receiver_type(&ctx, &to_extract) { + if receiver_type.is_mutable_reference() { RefKind::MutRef } else { RefKind::Ref } } else { - false + RefKind::None }; let anchor = Anchor::from(&to_extract)?; @@ -83,7 +83,11 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option None => to_extract.syntax().text_range(), }; - let reference_modifier = if is_mutable_reference { "&mut " } else { "" }; + let reference_modifier = match ref_kind { + RefKind::MutRef => "&mut ", + RefKind::Ref => "&", + RefKind::None => "" + }; match anchor { Anchor::Before(_) | Anchor::Replace(_) => { @@ -173,6 +177,13 @@ fn get_receiver(expression: ast::Expr) -> Option<ast::Expr> { } #[derive(Debug)] +enum RefKind { + Ref, + MutRef, + None +} + +#[derive(Debug)] enum Anchor { Before(SyntaxNode), Replace(ast::ExprStmt), @@ -986,4 +997,98 @@ fn foo(f: &mut Y) { }"#, ); } + + #[test] + fn test_extract_var_reference_parameter() { + check_assist( + extract_variable, + r#" +struct X; + +impl X { + fn do_thing(&self) { + + } +} + +struct S { + sub: X +} + +fn foo(s: &S) { + $0s.sub$0.do_thing(); +}"#, + r#" +struct X; + +impl X { + fn do_thing(&self) { + + } +} + +struct S { + sub: X +} + +fn foo(s: &S) { + let $0x = &s.sub; + x.do_thing(); +}"#, + ); + } + + #[test] + fn test_extract_var_reference_parameter_deep_nesting() { + check_assist( + extract_variable, + r#" +struct Z; +impl Z { + fn do_thing(&self) { + + } +} + +struct Y { + field: Z +} + +struct X { + field: Y +} + +struct S { + sub: X +} + +fn foo(s: &S) { + $0s.sub.field.field$0.do_thing(); +}"#, + r#" +struct Z; +impl Z { + fn do_thing(&self) { + + } +} + +struct Y { + field: Z +} + +struct X { + field: Y +} + +struct S { + sub: X +} + +fn foo(s: &S) { + let $0z = &s.sub.field.field; + z.do_thing(); +}"#, + ); + } } |