Skip to content

Commit 2c7e99b

Browse files
committed
Sort unions
1 parent b31bf74 commit 2c7e99b

File tree

1 file changed

+83
-35
lines changed

1 file changed

+83
-35
lines changed

crates/ide_assists/src/handlers/sort_items.rs

Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use std::cmp::Ordering;
22

3-
use hir::known::Option;
43
use itertools::Itertools;
54

65
use syntax::{
76
ast::{self, NameOwner},
8-
ted, AstNode,
7+
ted, AstNode, TextRange,
98
};
109

1110
use crate::{utils::get_methods, AssistContext, AssistId, AssistKind, Assists};
@@ -18,12 +17,45 @@ pub(crate) fn sort_items(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
1817
} else if let Some(impl_ast) = ctx.find_node_at_offset::<ast::Impl>() {
1918
add_sort_methods_assist(acc, impl_ast.assoc_item_list()?)
2019
} else if let Some(struct_ast) = ctx.find_node_at_offset::<ast::Struct>() {
21-
add_sort_fields_assist(acc, struct_ast.field_list()?)
20+
match struct_ast.field_list() {
21+
Some(ast::FieldList::RecordFieldList(it)) => add_sort_fields_assist(acc, it),
22+
_ => None,
23+
}
24+
} else if let Some(union_ast) = ctx.find_node_at_offset::<ast::Union>() {
25+
add_sort_fields_assist(acc, union_ast.record_field_list()?)
2226
} else {
2327
None
2428
}
2529
}
2630

31+
trait AddRewrite {
32+
fn add_rewrite<T: AstNode>(
33+
&mut self,
34+
label: &str,
35+
old: Vec<T>,
36+
new: Vec<T>,
37+
target: TextRange,
38+
) -> Option<()>;
39+
}
40+
41+
impl AddRewrite for Assists {
42+
fn add_rewrite<T: AstNode>(
43+
&mut self,
44+
label: &str,
45+
old: Vec<T>,
46+
new: Vec<T>,
47+
target: TextRange,
48+
) -> Option<()> {
49+
self.add(AssistId("sort_items", AssistKind::RefactorRewrite), label, target, |builder| {
50+
let mutable: Vec<_> = old.into_iter().map(|it| builder.make_mut(it)).collect();
51+
mutable
52+
.into_iter()
53+
.zip(new)
54+
.for_each(|(old, new)| ted::replace(old.syntax(), new.clone_for_update().syntax()));
55+
})
56+
}
57+
}
58+
2759
fn add_sort_methods_assist(acc: &mut Assists, item_list: ast::AssocItemList) -> Option<()> {
2860
let methods = get_methods(&item_list);
2961
let sorted = sort_by_name(&methods);
@@ -33,47 +65,26 @@ fn add_sort_methods_assist(acc: &mut Assists, item_list: ast::AssocItemList) ->
3365
return None;
3466
}
3567

36-
acc.add(
37-
AssistId("sort_items", AssistKind::RefactorRewrite),
38-
"Sort methods alphabetically",
39-
item_list.syntax().text_range(),
40-
|builder| {
41-
let methods = methods.into_iter().map(|fn_| builder.make_mut(fn_)).collect::<Vec<_>>();
42-
methods
43-
.into_iter()
44-
.zip(sorted)
45-
.for_each(|(old, new)| ted::replace(old.syntax(), new.clone_for_update().syntax()));
46-
},
47-
)
68+
acc.add_rewrite("Sort methods alphabetically", methods, sorted, item_list.syntax().text_range())
4869
}
4970

50-
fn add_sort_fields_assist(acc: &mut Assists, field_list: ast::FieldList) -> Option<()> {
51-
fn record_fields(field_list: &ast::FieldList) -> Option<Vec<ast::RecordField>> {
52-
match field_list {
53-
ast::FieldList::RecordFieldList(it) => Some(it.fields().collect()),
54-
ast::FieldList::TupleFieldList(_) => None,
55-
}
56-
}
57-
58-
let fields = record_fields(&field_list)?;
71+
fn add_sort_fields_assist(
72+
acc: &mut Assists,
73+
record_field_list: ast::RecordFieldList,
74+
) -> Option<()> {
75+
let fields: Vec<_> = record_field_list.fields().collect();
5976
let sorted = sort_by_name(&fields);
6077

6178
if fields == sorted {
6279
cov_mark::hit!(not_applicable_if_sorted);
6380
return None;
6481
}
6582

66-
acc.add(
67-
AssistId("sort_items", AssistKind::RefactorRewrite),
68-
"Sort methods alphabetically",
69-
field_list.syntax().text_range(),
70-
|builder| {
71-
let methods = fields.into_iter().map(|fn_| builder.make_mut(fn_)).collect::<Vec<_>>();
72-
methods
73-
.into_iter()
74-
.zip(sorted)
75-
.for_each(|(old, new)| ted::replace(old.syntax(), new.clone_for_update().syntax()));
76-
},
83+
acc.add_rewrite(
84+
"Sort fields alphabetically",
85+
fields,
86+
sorted,
87+
record_field_list.syntax().text_range(),
7788
)
7889
}
7990

@@ -147,6 +158,22 @@ $0struct Bar {
147158
)
148159
}
149160

161+
#[test]
162+
fn not_applicable_if_union_sorted() {
163+
cov_mark::check!(not_applicable_if_sorted);
164+
165+
check_assist_not_applicable(
166+
sort_items,
167+
r#"
168+
$0union Bar {
169+
a: u32,
170+
b: u8,
171+
c: u64,
172+
}
173+
"#,
174+
)
175+
}
176+
150177
#[test]
151178
fn sort_trait() {
152179
check_assist(
@@ -255,6 +282,27 @@ struct Bar {
255282
a: usize,
256283
aaa: u8,
257284
b: u8,
285+
}
286+
"#,
287+
)
288+
}
289+
290+
#[test]
291+
fn sort_union() {
292+
check_assist(
293+
sort_items,
294+
r#"
295+
$0union Bar {
296+
b: u8,
297+
a: u32,
298+
c: u64,
299+
}
300+
"#,
301+
r#"
302+
union Bar {
303+
a: u32,
304+
b: u8,
305+
c: u64,
258306
}
259307
"#,
260308
)

0 commit comments

Comments
 (0)