]> git.lizzy.rs Git - rust.git/commitdiff
reduce duplication
authorAleksey Kladov <aleksey.kladov@gmail.com>
Sun, 23 May 2021 20:13:35 +0000 (23:13 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Sun, 23 May 2021 20:13:35 +0000 (23:13 +0300)
crates/ide_assists/src/handlers/generate_getter.rs
crates/ide_assists/src/handlers/generate_getter_mut.rs [deleted file]
crates/ide_assists/src/lib.rs
crates/ide_assists/src/tests.rs

index df7d1bb9541ab68b8ff83da6db39b1b2c01b0168..e01985112d3f73857d36fc609eb4f90193dba065 100644 (file)
 // }
 // ```
 pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
+    generate_getter_impl(acc, ctx, false)
+}
+
+// Assist: generate_getter_mut
+//
+// Generate a mut getter method.
+//
+// ```
+// struct Person {
+//     nam$0e: String,
+// }
+// ```
+// ->
+// ```
+// struct Person {
+//     name: String,
+// }
+//
+// impl Person {
+//     /// Get a mutable reference to the person's name.
+//     fn name_mut(&mut self) -> &mut String {
+//         &mut self.name
+//     }
+// }
+// ```
+pub(crate) fn generate_getter_mut(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
+    generate_getter_impl(acc, ctx, true)
+}
+
+pub(crate) fn generate_getter_impl(
+    acc: &mut Assists,
+    ctx: &AssistContext,
+    mutable: bool,
+) -> Option<()> {
     let strukt = ctx.find_node_at_offset::<ast::Struct>()?;
     let field = ctx.find_node_at_offset::<ast::RecordField>()?;
 
@@ -37,22 +71,26 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
     let field_ty = field.ty()?;
 
     // Return early if we've found an existing fn
-    let fn_name = to_lower_snake_case(&field_name.to_string());
+    let mut fn_name = to_lower_snake_case(&field_name.to_string());
+    if mutable {
+        format_to!(fn_name, "_mut");
+    }
     let impl_def = find_struct_impl(&ctx, &ast::Adt::Struct(strukt.clone()), fn_name.as_str())?;
 
+    let (id, label) = if mutable {
+        ("generate_getter_mut", "Generate a mut getter method")
+    } else {
+        ("generate_getter", "Generate a getter method")
+    };
     let target = field.syntax().text_range();
     acc.add_group(
         &GroupLabel("Generate getter/setter".to_owned()),
-        AssistId("generate_getter", AssistKind::Generate),
-        "Generate a getter method",
+        AssistId(id, AssistKind::Generate),
+        label,
         target,
         |builder| {
             let mut buf = String::with_capacity(512);
 
-            let fn_name_spaced = fn_name.replace('_', " ");
-            let strukt_name_spaced =
-                to_lower_snake_case(&strukt_name.to_string()).replace('_', " ");
-
             if impl_def.is_some() {
                 buf.push('\n');
             }
@@ -60,16 +98,18 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
             let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v));
             format_to!(
                 buf,
-                "    /// Get a reference to the {}'s {}.
-    {}fn {}(&self) -> &{} {{
-        &self.{}
+                "    /// Get a {}reference to the {}'s {}.
+    {}fn {}(&{mut_}self) -> &{mut_}{} {{
+        &{mut_}self.{}
     }}",
-                strukt_name_spaced,
-                fn_name_spaced,
+                mutable.then(|| "mutable ").unwrap_or_default(),
+                to_lower_snake_case(&strukt_name.to_string()).replace('_', " "),
+                fn_name.trim_end_matches("_mut").replace('_', " "),
                 vis,
                 fn_name,
                 field_ty,
-                fn_name,
+                field_name,
+                mut_ = mutable.then(|| "mut ").unwrap_or_default(),
             );
 
             let start_offset = impl_def
@@ -190,3 +230,110 @@ fn count(&self) -> &usize {
         );
     }
 }
+
+#[cfg(test)]
+mod tests_mut {
+    use crate::tests::{check_assist, check_assist_not_applicable};
+
+    use super::*;
+
+    fn check_not_applicable(ra_fixture: &str) {
+        check_assist_not_applicable(generate_getter_mut, ra_fixture)
+    }
+
+    #[test]
+    fn test_generate_getter_mut_from_field() {
+        check_assist(
+            generate_getter_mut,
+            r#"
+struct Context<T: Clone> {
+    dat$0a: T,
+}"#,
+            r#"
+struct Context<T: Clone> {
+    data: T,
+}
+
+impl<T: Clone> Context<T> {
+    /// Get a mutable reference to the context's data.
+    fn data_mut(&mut self) -> &mut T {
+        &mut self.data
+    }
+}"#,
+        );
+    }
+
+    #[test]
+    fn test_generate_getter_mut_already_implemented() {
+        check_not_applicable(
+            r#"
+struct Context<T: Clone> {
+    dat$0a: T,
+}
+
+impl<T: Clone> Context<T> {
+    fn data_mut(&mut self) -> &mut T {
+        &mut self.data
+    }
+}"#,
+        );
+    }
+
+    #[test]
+    fn test_generate_getter_mut_from_field_with_visibility_marker() {
+        check_assist(
+            generate_getter_mut,
+            r#"
+pub(crate) struct Context<T: Clone> {
+    dat$0a: T,
+}"#,
+            r#"
+pub(crate) struct Context<T: Clone> {
+    data: T,
+}
+
+impl<T: Clone> Context<T> {
+    /// Get a mutable reference to the context's data.
+    pub(crate) fn data_mut(&mut self) -> &mut T {
+        &mut self.data
+    }
+}"#,
+        );
+    }
+
+    #[test]
+    fn test_multiple_generate_getter_mut() {
+        check_assist(
+            generate_getter_mut,
+            r#"
+struct Context<T: Clone> {
+    data: T,
+    cou$0nt: usize,
+}
+
+impl<T: Clone> Context<T> {
+    /// Get a mutable reference to the context's data.
+    fn data_mut(&mut self) -> &mut T {
+        &mut self.data
+    }
+}"#,
+            r#"
+struct Context<T: Clone> {
+    data: T,
+    count: usize,
+}
+
+impl<T: Clone> Context<T> {
+    /// Get a mutable reference to the context's data.
+    fn data_mut(&mut self) -> &mut T {
+        &mut self.data
+    }
+
+    /// Get a mutable reference to the context's count.
+    fn count_mut(&mut self) -> &mut usize {
+        &mut self.count
+    }
+}"#,
+        );
+    }
+}
diff --git a/crates/ide_assists/src/handlers/generate_getter_mut.rs b/crates/ide_assists/src/handlers/generate_getter_mut.rs
deleted file mode 100644 (file)
index 821c2ee..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-use stdx::{format_to, to_lower_snake_case};
-use syntax::ast::{self, AstNode, NameOwner, VisibilityOwner};
-
-use crate::{
-    utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
-    AssistContext, AssistId, AssistKind, Assists, GroupLabel,
-};
-
-// Assist: generate_getter_mut
-//
-// Generate a mut getter method.
-//
-// ```
-// struct Person {
-//     nam$0e: String,
-// }
-// ```
-// ->
-// ```
-// struct Person {
-//     name: String,
-// }
-//
-// impl Person {
-//     /// Get a mutable reference to the person's name.
-//     fn name_mut(&mut self) -> &mut String {
-//         &mut self.name
-//     }
-// }
-// ```
-pub(crate) fn generate_getter_mut(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
-    let strukt = ctx.find_node_at_offset::<ast::Struct>()?;
-    let field = ctx.find_node_at_offset::<ast::RecordField>()?;
-
-    let strukt_name = strukt.name()?;
-    let field_name = field.name()?;
-    let field_ty = field.ty()?;
-
-    // Return early if we've found an existing fn
-    let fn_name = to_lower_snake_case(&field_name.to_string());
-    let impl_def = find_struct_impl(
-        &ctx,
-        &ast::Adt::Struct(strukt.clone()),
-        format!("{}_mut", fn_name).as_str(),
-    )?;
-
-    let target = field.syntax().text_range();
-    acc.add_group(
-        &GroupLabel("Generate getter/setter".to_owned()),
-        AssistId("generate_getter_mut", AssistKind::Generate),
-        "Generate a mut getter method",
-        target,
-        |builder| {
-            let mut buf = String::with_capacity(512);
-            let fn_name_spaced = fn_name.replace('_', " ");
-            let strukt_name_spaced =
-                to_lower_snake_case(&strukt_name.to_string()).replace('_', " ");
-
-            if impl_def.is_some() {
-                buf.push('\n');
-            }
-
-            let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v));
-            format_to!(
-                buf,
-                "    /// Get a mutable reference to the {}'s {}.
-    {}fn {}_mut(&mut self) -> &mut {} {{
-        &mut self.{}
-    }}",
-                strukt_name_spaced,
-                fn_name_spaced,
-                vis,
-                fn_name,
-                field_ty,
-                fn_name,
-            );
-
-            let start_offset = impl_def
-                .and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
-                .unwrap_or_else(|| {
-                    buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
-                    strukt.syntax().text_range().end()
-                });
-
-            builder.insert(start_offset, buf);
-        },
-    )
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable};
-
-    use super::*;
-
-    fn check_not_applicable(ra_fixture: &str) {
-        check_assist_not_applicable(generate_getter_mut, ra_fixture)
-    }
-
-    #[test]
-    fn test_generate_getter_mut_from_field() {
-        check_assist(
-            generate_getter_mut,
-            r#"
-struct Context<T: Clone> {
-    dat$0a: T,
-}"#,
-            r#"
-struct Context<T: Clone> {
-    data: T,
-}
-
-impl<T: Clone> Context<T> {
-    /// Get a mutable reference to the context's data.
-    fn data_mut(&mut self) -> &mut T {
-        &mut self.data
-    }
-}"#,
-        );
-    }
-
-    #[test]
-    fn test_generate_getter_mut_already_implemented() {
-        check_not_applicable(
-            r#"
-struct Context<T: Clone> {
-    dat$0a: T,
-}
-
-impl<T: Clone> Context<T> {
-    fn data_mut(&mut self) -> &mut T {
-        &mut self.data
-    }
-}"#,
-        );
-    }
-
-    #[test]
-    fn test_generate_getter_mut_from_field_with_visibility_marker() {
-        check_assist(
-            generate_getter_mut,
-            r#"
-pub(crate) struct Context<T: Clone> {
-    dat$0a: T,
-}"#,
-            r#"
-pub(crate) struct Context<T: Clone> {
-    data: T,
-}
-
-impl<T: Clone> Context<T> {
-    /// Get a mutable reference to the context's data.
-    pub(crate) fn data_mut(&mut self) -> &mut T {
-        &mut self.data
-    }
-}"#,
-        );
-    }
-
-    #[test]
-    fn test_multiple_generate_getter_mut() {
-        check_assist(
-            generate_getter_mut,
-            r#"
-struct Context<T: Clone> {
-    data: T,
-    cou$0nt: usize,
-}
-
-impl<T: Clone> Context<T> {
-    /// Get a mutable reference to the context's data.
-    fn data_mut(&mut self) -> &mut T {
-        &mut self.data
-    }
-}"#,
-            r#"
-struct Context<T: Clone> {
-    data: T,
-    count: usize,
-}
-
-impl<T: Clone> Context<T> {
-    /// Get a mutable reference to the context's data.
-    fn data_mut(&mut self) -> &mut T {
-        &mut self.data
-    }
-
-    /// Get a mutable reference to the context's count.
-    fn count_mut(&mut self) -> &mut usize {
-        &mut self.count
-    }
-}"#,
-        );
-    }
-}
index 4cd82f8c16da7bc12e9531dcdb534abb4823eb7a..16af72927b02137f440e6d7cdd1c092a17c717b2 100644 (file)
@@ -206,7 +206,6 @@ mod handlers {
     mod generate_enum_projection_method;
     mod generate_from_impl_for_enum;
     mod generate_function;
-    mod generate_getter_mut;
     mod generate_getter;
     mod generate_impl;
     mod generate_new;
@@ -276,8 +275,8 @@ pub(crate) fn all() -> &'static [Handler] {
             generate_enum_projection_method::generate_enum_try_into_method,
             generate_from_impl_for_enum::generate_from_impl_for_enum,
             generate_function::generate_function,
-            generate_getter_mut::generate_getter_mut,
             generate_getter::generate_getter,
+            generate_getter::generate_getter_mut,
             generate_impl::generate_impl,
             generate_new::generate_new,
             generate_setter::generate_setter,
index 6a9231e07879970fbec81aa96b7f8146bd873c56..2b7c2d581e9afe3bf081bd1db8712bdb5a8f9bc3 100644 (file)
@@ -215,8 +215,8 @@ fn assist_order_field_struct() {
 
     assert_eq!(assists.next().expect("expected assist").label, "Change visibility to pub(crate)");
     assert_eq!(assists.next().expect("expected assist").label, "Generate `Deref` impl using `bar`");
-    assert_eq!(assists.next().expect("expected assist").label, "Generate a mut getter method");
     assert_eq!(assists.next().expect("expected assist").label, "Generate a getter method");
+    assert_eq!(assists.next().expect("expected assist").label, "Generate a mut getter method");
     assert_eq!(assists.next().expect("expected assist").label, "Generate a setter method");
     assert_eq!(assists.next().expect("expected assist").label, "Add `#[derive]`");
 }