about summary refs log tree commit diff
diff options
context:
space:
mode:
authorponyii <ponyii@protonmail.com>2023-05-08 22:26:50 +0400
committerponyii <ponyii@protonmail.com>2023-05-10 16:35:48 +0400
commite07d6382de5b8764aa38eccdf59a4dd8b6243a6c (patch)
tree9f1149b34d67506b7d452fa723b08577e585b751
parenta0db4781dca403a33fcc9209f71fa1a26387d05c (diff)
`add_missing_impl_members` no longer breaks indentation
-rw-r--r--crates/ide-assists/src/handlers/add_missing_impl_members.rs104
-rw-r--r--crates/ide-assists/src/utils.rs4
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs2
3 files changed, 106 insertions, 4 deletions
diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index 9e4e6c1daf7..4cc04fff633 100644
--- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -1511,11 +1511,111 @@ fn main() {
     struct S;
     impl Tr for S {
         fn method() {
-        ${0:todo!()}
-    }
+            ${0:todo!()}
+        }
     }
 }
 "#,
         );
     }
+
+    #[test]
+    fn test_add_missing_impl_members_indentation() {
+        // few trait members, no braces
+        check_assist(
+            add_missing_impl_members,
+            r#"
+mod m {
+    trait Foo { fn foo(&self); }
+    struct S;
+    impl Foo for S$0
+}"#,
+            r#"
+mod m {
+    trait Foo { fn foo(&self); }
+    struct S;
+    impl Foo for S {
+        fn foo(&self) {
+            ${0:todo!()}
+        }
+    }
+}"#,
+        );
+        // few trait members, empty impl def.
+        check_assist(
+            add_missing_impl_members,
+            r#"
+mod m {
+    trait Foo { fn foo(&self); }
+    struct S;
+    impl Foo for S { $0 }
+}"#,
+            r#"
+mod m {
+    trait Foo { fn foo(&self); }
+    struct S;
+    impl Foo for S {
+        fn foo(&self) {
+            ${0:todo!()}
+        }
+    }
+}"#,
+        );
+        // todo - in mod and outside
+        check_assist(
+            add_missing_impl_members,
+            r#"
+mod m {
+    trait Foo {
+        type Output;
+
+        const CONST: usize = 42;
+        const CONST_2: i32;
+
+        fn foo(&self);
+        fn bar(&self);
+        fn baz(&self);
+    }
+
+    struct S;
+
+    impl Foo for S {
+        fn bar(&self) {}
+$0
+    }
+}"#,
+            r#"
+mod m {
+    trait Foo {
+        type Output;
+
+        const CONST: usize = 42;
+        const CONST_2: i32;
+
+        fn foo(&self);
+        fn bar(&self);
+        fn baz(&self);
+    }
+
+    struct S;
+
+    impl Foo for S {
+        fn bar(&self) {}
+
+        $0type Output;
+
+        const CONST_2: i32;
+
+        fn foo(&self) {
+            todo!()
+        }
+
+        fn baz(&self) {
+            todo!()
+        }
+
+    }
+}"#,
+        );
+    }
 }
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index 77f4b0e3e02..1c9d4157cd6 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -9,7 +9,7 @@ use stdx::format_to;
 use syntax::{
     ast::{
         self,
-        edit::{self, AstNodeEdit},
+        edit::{AstNodeEdit, IndentLevel},
         edit_in_place::{AttrsOwnerEdit, Removable},
         make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
     },
@@ -154,7 +154,7 @@ pub fn add_trait_assoc_items_to_impl(
         match &item {
             ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
                 let body = make::block_expr(None, Some(make::ext::expr_todo()))
-                    .indent(edit::IndentLevel(1));
+                    .indent(IndentLevel::from_node(impl_.syntax()) + 1);
                 ted::replace(fn_.get_or_create_body().syntax(), body.clone_for_update().syntax())
             }
             ast::AssocItem::TypeAlias(type_alias) => {
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index a493c92e7da..995e8d8d152 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -465,6 +465,8 @@ impl ast::Impl {
 }
 
 impl ast::AssocItemList {
+    /// Attention! This function does align the first line of `item` with respect to `self`,
+    /// but it does _not_ change indentation of other lines (if any).
     pub fn add_item(&self, item: ast::AssocItem) {
         let (indent, position, whitespace) = match self.assoc_items().last() {
             Some(last_item) => (