Skip to content

Commit

Permalink
Restrict "sort items" assist inside Impl & Trait
Browse files Browse the repository at this point in the history
This fixes the applicability of the "sort items alphabetically" assist
when the selection is inside a `Trait` or `Impl`. It's now tested if the
selection is inside or overlaps with an inner node, e.g. associated
const or type alias, function.
  • Loading branch information
justahero committed Apr 17, 2023
1 parent 600283f commit c1712e5
Showing 1 changed file with 103 additions and 6 deletions.
109 changes: 103 additions & 6 deletions crates/ide-assists/src/handlers/sort_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()?)
Expand All @@ -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
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -218,6 +230,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);
Expand All @@ -233,6 +290,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);
Expand Down Expand Up @@ -460,6 +532,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(
Expand Down

0 comments on commit c1712e5

Please sign in to comment.