about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide-assists/src/handlers/sort_items.rs109
1 files changed, 103 insertions, 6 deletions
diff --git a/crates/ide-assists/src/handlers/sort_items.rs b/crates/ide-assists/src/handlers/sort_items.rs
index 63e350e155f..3a0121f55fa 100644
--- a/crates/ide-assists/src/handlers/sort_items.rs
+++ b/crates/ide-assists/src/handlers/sort_items.rs
@@ -87,11 +87,7 @@ pub(crate) fn sort_items(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
         return None;
     }
 
-    if let Some(trait_ast) = ctx.find_node_at_offset::<ast::Trait>() {
-        add_sort_methods_assist(acc, trait_ast.assoc_item_list()?)
-    } else if let Some(impl_ast) = ctx.find_node_at_offset::<ast::Impl>() {
-        add_sort_methods_assist(acc, impl_ast.assoc_item_list()?)
-    } else if let Some(struct_ast) = ctx.find_node_at_offset::<ast::Struct>() {
+    if let Some(struct_ast) = ctx.find_node_at_offset::<ast::Struct>() {
         add_sort_field_list_assist(acc, struct_ast.field_list())
     } else if let Some(union_ast) = ctx.find_node_at_offset::<ast::Union>() {
         add_sort_fields_assist(acc, union_ast.record_field_list()?)
@@ -103,6 +99,10 @@ pub(crate) fn sort_items(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
         add_sort_fields_assist(acc, enum_struct_variant_ast)
     } else if let Some(enum_ast) = ctx.find_node_at_offset::<ast::Enum>() {
         add_sort_variants_assist(acc, enum_ast.variant_list()?)
+    } else if let Some(trait_ast) = ctx.find_node_at_offset::<ast::Trait>() {
+        add_sort_methods_assist(acc, ctx, trait_ast.assoc_item_list()?)
+    } else if let Some(impl_ast) = ctx.find_node_at_offset::<ast::Impl>() {
+        add_sort_methods_assist(acc, ctx, impl_ast.assoc_item_list()?)
     } else {
         None
     }
@@ -148,7 +148,19 @@ fn add_sort_field_list_assist(acc: &mut Assists, field_list: Option<ast::FieldLi
     }
 }
 
-fn add_sort_methods_assist(acc: &mut Assists, item_list: ast::AssocItemList) -> Option<()> {
+fn add_sort_methods_assist(
+    acc: &mut Assists,
+    ctx: &AssistContext<'_>,
+    item_list: ast::AssocItemList,
+) -> Option<()> {
+    let selection = ctx.selection_trimmed();
+
+    // ignore assist if the selection intersects with an associated item.
+    if item_list.assoc_items().any(|item| item.syntax().text_range().intersect(selection).is_some())
+    {
+        return None;
+    }
+
     let methods = get_methods(&item_list);
     let sorted = sort_by_name(&methods);
 
@@ -219,6 +231,51 @@ mod tests {
     use super::*;
 
     #[test]
+    fn not_applicable_if_selection_in_fn_body() {
+        check_assist_not_applicable(
+            sort_items,
+            r#"
+struct S;
+impl S {
+    fn func2() {
+        $0 bar $0
+    }
+    fn func() {}
+}
+        "#,
+        )
+    }
+
+    #[test]
+    fn not_applicable_if_selection_at_associated_const() {
+        check_assist_not_applicable(
+            sort_items,
+            r#"
+struct S;
+impl S {
+    fn func2() {}
+    fn func() {}
+    const C: () = $0()$0;
+}
+        "#,
+        )
+    }
+
+    #[test]
+    fn not_applicable_if_selection_overlaps_nodes() {
+        check_assist_not_applicable(
+            sort_items,
+            r#"
+struct S;
+impl $0S {
+    fn$0 func2() {}
+    fn func() {}
+}
+        "#,
+        )
+    }
+
+    #[test]
     fn not_applicable_if_no_selection() {
         cov_mark::check!(not_applicable_if_no_selection);
 
@@ -234,6 +291,21 @@ t$0rait Bar {
     }
 
     #[test]
+    fn not_applicable_if_selection_in_trait_fn_body() {
+        check_assist_not_applicable(
+            sort_items,
+            r#"
+trait Bar {
+    fn b() {
+        $0 hello $0
+    }
+    fn a();
+}
+        "#,
+        )
+    }
+
+    #[test]
     fn not_applicable_if_trait_empty() {
         cov_mark::check!(not_applicable_if_sorted_or_empty_or_single);
 
@@ -461,6 +533,31 @@ struct Bar {
     }
 
     #[test]
+    fn sort_struct_inside_a_function() {
+        check_assist(
+            sort_items,
+            r#"
+fn hello() {
+    $0struct Bar$0 {
+        b: u8,
+        a: u32,
+        c: u64,
+    }
+}
+        "#,
+            r#"
+fn hello() {
+    struct Bar {
+        a: u32,
+        b: u8,
+        c: u64,
+    }
+}
+        "#,
+        )
+    }
+
+    #[test]
     fn sort_generic_struct_with_lifetime() {
         check_assist(
             sort_items,