Auto merge of #14591 - justahero:gh-14516, r=Veykril
Restrict "sort items" assist for traits & impls This restricts the "sort items alphabetically" assist when the selection is inside a `Impl` or `Trait` node & intersects with one of the associated items. It re-orders the conditional checks of AST nodes in the `sort_items` function to check for more specific nodes first before checking `Trait` or `Impl` nodes. The `AssistContext` is passed into the `add_sort_methods_assist` function to check if the selection intersects with any inner items, e.g. associated const or type alias, function. In this case the assist does not apply. Fixes: #14516
This commit is contained in:
commit
5111207d9a
@ -87,11 +87,7 @@ pub(crate) fn sort_items(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(trait_ast) = ctx.find_node_at_offset::<ast::Trait>() {
|
if let Some(struct_ast) = ctx.find_node_at_offset::<ast::Struct>() {
|
||||||
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>() {
|
|
||||||
add_sort_field_list_assist(acc, struct_ast.field_list())
|
add_sort_field_list_assist(acc, struct_ast.field_list())
|
||||||
} else if let Some(union_ast) = ctx.find_node_at_offset::<ast::Union>() {
|
} else if let Some(union_ast) = ctx.find_node_at_offset::<ast::Union>() {
|
||||||
add_sort_fields_assist(acc, union_ast.record_field_list()?)
|
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)
|
add_sort_fields_assist(acc, enum_struct_variant_ast)
|
||||||
} else if let Some(enum_ast) = ctx.find_node_at_offset::<ast::Enum>() {
|
} else if let Some(enum_ast) = ctx.find_node_at_offset::<ast::Enum>() {
|
||||||
add_sort_variants_assist(acc, enum_ast.variant_list()?)
|
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 {
|
} else {
|
||||||
None
|
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 methods = get_methods(&item_list);
|
||||||
let sorted = sort_by_name(&methods);
|
let sorted = sort_by_name(&methods);
|
||||||
|
|
||||||
@ -218,6 +230,51 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
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]
|
#[test]
|
||||||
fn not_applicable_if_no_selection() {
|
fn not_applicable_if_no_selection() {
|
||||||
cov_mark::check!(not_applicable_if_no_selection);
|
cov_mark::check!(not_applicable_if_no_selection);
|
||||||
@ -233,6 +290,21 @@ fn not_applicable_if_no_selection() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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]
|
#[test]
|
||||||
fn not_applicable_if_trait_empty() {
|
fn not_applicable_if_trait_empty() {
|
||||||
cov_mark::check!(not_applicable_if_sorted_or_empty_or_single);
|
cov_mark::check!(not_applicable_if_sorted_or_empty_or_single);
|
||||||
@ -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]
|
#[test]
|
||||||
fn sort_generic_struct_with_lifetime() {
|
fn sort_generic_struct_with_lifetime() {
|
||||||
check_assist(
|
check_assist(
|
||||||
|
Loading…
Reference in New Issue
Block a user