Skip to content

Commit 7787554

Browse files
committed
Attempt rust-lang#1 Alphabetically Sorting Methods
1 parent 41321d9 commit 7787554

File tree

2 files changed

+244
-0
lines changed

2 files changed

+244
-0
lines changed
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
use ast::{AssocItemList, Fn};
2+
use itertools::Itertools;
3+
use rustc_hash::FxHashMap;
4+
5+
use hir::{Adt, ModuleDef, PathResolution, Semantics, Struct};
6+
use ide_db::RootDatabase;
7+
use syntax::{
8+
algo,
9+
ast::{self, AssocItem, NameOwner},
10+
match_ast, AstNode, SyntaxKind,
11+
SyntaxKind::*,
12+
SyntaxNode,
13+
};
14+
15+
use crate::{AssistContext, AssistId, AssistKind, Assists};
16+
17+
// Assist: reorder_methods_sort
18+
//
19+
// Reorder the fields of record literals and record patterns in the same order as in
20+
// the definition.
21+
//
22+
// ```
23+
// struct Foo {foo: i32, bar: i32};
24+
// const test: Foo = <|>Foo {bar: 0, foo: 1}
25+
// ```
26+
// ->
27+
// ```
28+
// struct Foo {foo: i32, bar: i32};
29+
// const test: Foo = Foo {foo: 1, bar: 0}
30+
// ```
31+
//
32+
pub(crate) fn reorder_methods_sort(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
33+
reorder(acc, ctx) //.or_else(|| reorder::<ast::RecordPat>(acc, ctx))
34+
}
35+
36+
fn reorder(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
37+
let impl_ast = ctx.find_node_at_offset::<ast::Impl>()?;
38+
39+
let items = impl_ast.assoc_item_list()?;
40+
41+
let methods = get_methods(&items);
42+
let sorted: Vec<_> =
43+
methods.iter().cloned().sorted_by_key(|f| f.name().unwrap().text().to_string()).collect();
44+
45+
let target = items.syntax().text_range();
46+
acc.add(
47+
AssistId("reorder_methods_sort", AssistKind::RefactorRewrite),
48+
"Sort impl methods",
49+
target,
50+
|edit| {
51+
let mut rewriter = algo::SyntaxRewriter::default();
52+
for (old, new) in methods.iter().zip(&sorted) {
53+
rewriter.replace(old.syntax(), new.syntax());
54+
}
55+
edit.rewrite(rewriter);
56+
},
57+
)
58+
59+
// println!("Fns: {:?}", fns);
60+
// items.syntax().text_range();
61+
62+
// let path = record.syntax().children().find_map(ast::Path::cast)?;
63+
64+
// println!("Path: {}", path);
65+
66+
// let ranks = compute_fields_ranks(&path, &ctx)?;
67+
68+
// let fields = get_fields(&record.syntax());
69+
// let sorted_fields = sorted_by_rank(&fields, |node| {
70+
// *ranks.get(&get_field_name(node)).unwrap_or(&usize::max_value())
71+
// });
72+
73+
// if sorted_fields == fields {
74+
// return None;
75+
// }
76+
77+
// let target = record.syntax().text_range();
78+
// acc.add(
79+
// AssistId("reorder_methods_sort", AssistKind::RefactorRewrite),
80+
// "Reorder record fields",
81+
// target,
82+
// |edit| {
83+
// let mut rewriter = algo::SyntaxRewriter::default();
84+
// for (old, new) in fields.iter().zip(&sorted_fields) {
85+
// rewriter.replace(old, new);
86+
// }
87+
// edit.rewrite(rewriter);
88+
// },
89+
// )
90+
}
91+
92+
fn get_methods(items: &AssocItemList) -> Vec<Fn> {
93+
items
94+
.assoc_items()
95+
.flat_map(|i| match i {
96+
AssocItem::Fn(f) => Some(f),
97+
_ => None,
98+
})
99+
.filter(|f| f.name().is_some())
100+
.collect()
101+
}
102+
103+
struct Foo {
104+
c: usize,
105+
}
106+
impl Foo {
107+
fn ten() -> usize {
108+
10
109+
}
110+
fn add(&mut self, b: usize) {
111+
self.c += b
112+
}
113+
fn sub(&mut self, b: usize) {
114+
self.c -= b
115+
}
116+
}
117+
118+
#[cfg(test)]
119+
mod tests {
120+
use crate::tests::{check_assist, check_assist_not_applicable};
121+
122+
use super::*;
123+
124+
#[test]
125+
fn not_applicable_if_sorted() {
126+
check_assist_not_applicable(
127+
reorder_methods_sort,
128+
r#"
129+
struct Foo {
130+
foo: i32,
131+
bar: i32,
132+
}
133+
134+
const test: Foo = <|>Foo { foo: 0, bar: 0 };
135+
"#,
136+
)
137+
}
138+
139+
#[test]
140+
fn trivial_empty_impl() {
141+
check_assist_not_applicable(
142+
reorder_methods_sort,
143+
r#"
144+
struct Foo {};
145+
<|>impl Foo {}
146+
"#,
147+
)
148+
}
149+
150+
#[test]
151+
fn reorder_impl_methods() {
152+
check_assist(
153+
reorder_methods_sort,
154+
r#"
155+
struct Foo {c: usize}
156+
157+
<|>impl Foo {
158+
fn sub(&mut self, b: usize) { self.c -= b }
159+
fn ten() -> usize { 10 }
160+
fn add(&mut self, b: usize) { self.c += b }
161+
}
162+
"#,
163+
r#"
164+
struct Foo {c: usize}
165+
166+
impl Foo {
167+
fn add(&mut self, b: usize) { self.c += b }
168+
fn sub(&mut self, b: usize) { self.c -= b }
169+
fn ten() -> usize { 10 }
170+
}
171+
"#,
172+
)
173+
}
174+
175+
#[test]
176+
fn reorder_struct_pattern() {
177+
check_assist(
178+
reorder_methods_sort,
179+
r#"
180+
struct Foo { foo: i64, bar: i64, baz: i64 }
181+
182+
fn f(f: Foo) -> {
183+
match f {
184+
<|>Foo { baz: 0, ref mut bar, .. } => (),
185+
_ => ()
186+
}
187+
}
188+
"#,
189+
r#"
190+
struct Foo { foo: i64, bar: i64, baz: i64 }
191+
192+
fn f(f: Foo) -> {
193+
match f {
194+
Foo { ref mut bar, baz: 0, .. } => (),
195+
_ => ()
196+
}
197+
}
198+
"#,
199+
)
200+
}
201+
202+
#[test]
203+
fn reorder_with_extra_field() {
204+
check_assist(
205+
reorder_methods_sort,
206+
r#"
207+
struct Foo {
208+
foo: String,
209+
bar: String,
210+
}
211+
212+
impl Foo {
213+
fn new() -> Foo {
214+
let foo = String::new();
215+
<|>Foo {
216+
bar: foo.clone(),
217+
extra: "Extra field",
218+
foo,
219+
}
220+
}
221+
}
222+
"#,
223+
r#"
224+
struct Foo {
225+
foo: String,
226+
bar: String,
227+
}
228+
229+
impl Foo {
230+
fn new() -> Foo {
231+
let foo = String::new();
232+
Foo {
233+
foo,
234+
bar: foo.clone(),
235+
extra: "Extra field",
236+
}
237+
}
238+
}
239+
"#,
240+
)
241+
}
242+
}

crates/assists/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ mod handlers {
155155
mod remove_mut;
156156
mod remove_unused_param;
157157
mod reorder_fields;
158+
mod reorder_methods_sort;
158159
mod replace_derive_with_manual_impl;
159160
mod replace_if_let_with_match;
160161
mod replace_impl_trait_with_generic;
@@ -207,6 +208,7 @@ mod handlers {
207208
remove_mut::remove_mut,
208209
remove_unused_param::remove_unused_param,
209210
reorder_fields::reorder_fields,
211+
reorder_methods_sort::reorder_methods_sort,
210212
replace_derive_with_manual_impl::replace_derive_with_manual_impl,
211213
replace_if_let_with_match::replace_if_let_with_match,
212214
replace_if_let_with_match::replace_match_with_if_let,

0 commit comments

Comments
 (0)