mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
Cleanup
This commit is contained in:
parent
e33959a888
commit
8b4240e026
1 changed files with 46 additions and 68 deletions
|
@ -1,9 +1,6 @@
|
||||||
use itertools::Itertools;
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use hir::{Adt, ModuleDef, PathResolution, Semantics, Struct};
|
use syntax::{algo, ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode};
|
||||||
use ide_db::RootDatabase;
|
|
||||||
use syntax::{algo, ast, match_ast, AstNode, SyntaxKind, SyntaxKind::*, SyntaxNode};
|
|
||||||
|
|
||||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||||
|
|
||||||
|
@ -23,26 +20,39 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||||
reorder::<ast::RecordExpr>(acc, ctx).or_else(|| reorder::<ast::RecordPat>(acc, ctx))
|
let record = ctx
|
||||||
}
|
.find_node_at_offset::<ast::RecordExpr>()
|
||||||
|
.map(|it| it.syntax().clone())
|
||||||
|
.or_else(|| ctx.find_node_at_offset::<ast::RecordPat>().map(|it| it.syntax().clone()))?;
|
||||||
|
|
||||||
fn reorder<R: AstNode>(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
let path = record.children().find_map(ast::Path::cast)?;
|
||||||
let record = ctx.find_node_at_offset::<R>()?;
|
|
||||||
let path = record.syntax().children().find_map(ast::Path::cast)?;
|
|
||||||
|
|
||||||
let ranks = compute_fields_ranks(&path, &ctx)?;
|
let ranks = compute_fields_ranks(&path, &ctx)?;
|
||||||
|
|
||||||
let fields = get_fields(&record.syntax());
|
let fields: Vec<SyntaxNode> = {
|
||||||
let sorted_fields = sorted_by_rank(&fields, |node| {
|
let field_kind = match record.kind() {
|
||||||
*ranks.get(&get_field_name(node)).unwrap_or(&usize::max_value())
|
RECORD_EXPR => RECORD_EXPR_FIELD,
|
||||||
});
|
RECORD_PAT => RECORD_PAT_FIELD,
|
||||||
|
_ => {
|
||||||
|
stdx::never!();
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
record.children().flat_map(|n| n.children()).filter(|n| n.kind() == field_kind).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
let sorted_fields = {
|
||||||
|
let mut fields = fields.clone();
|
||||||
|
fields.sort_by_key(|node| *ranks.get(&get_field_name(node)).unwrap_or(&usize::max_value()));
|
||||||
|
fields
|
||||||
|
};
|
||||||
|
|
||||||
if sorted_fields == fields {
|
if sorted_fields == fields {
|
||||||
cov_mark::hit!(reorder_sorted_fields);
|
cov_mark::hit!(reorder_sorted_fields);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = record.syntax().text_range();
|
let target = record.text_range();
|
||||||
acc.add(
|
acc.add(
|
||||||
AssistId("reorder_fields", AssistKind::RefactorRewrite),
|
AssistId("reorder_fields", AssistKind::RefactorRewrite),
|
||||||
"Reorder record fields",
|
"Reorder record fields",
|
||||||
|
@ -57,14 +67,6 @@ fn reorder<R: AstNode>(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fields_kind(node: &SyntaxNode) -> Vec<SyntaxKind> {
|
|
||||||
match node.kind() {
|
|
||||||
RECORD_EXPR => vec![RECORD_EXPR_FIELD],
|
|
||||||
RECORD_PAT => vec![RECORD_PAT_FIELD, IDENT_PAT],
|
|
||||||
_ => vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_field_name(node: &SyntaxNode) -> String {
|
fn get_field_name(node: &SyntaxNode) -> String {
|
||||||
let res = match_ast! {
|
let res = match_ast! {
|
||||||
match node {
|
match node {
|
||||||
|
@ -76,34 +78,20 @@ fn get_field_name(node: &SyntaxNode) -> String {
|
||||||
res.unwrap_or_default()
|
res.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fields(record: &SyntaxNode) -> Vec<SyntaxNode> {
|
|
||||||
let kinds = get_fields_kind(record);
|
|
||||||
record.children().flat_map(|n| n.children()).filter(|n| kinds.contains(&n.kind())).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sorted_by_rank(
|
|
||||||
fields: &[SyntaxNode],
|
|
||||||
get_rank: impl Fn(&SyntaxNode) -> usize,
|
|
||||||
) -> Vec<SyntaxNode> {
|
|
||||||
fields.iter().cloned().sorted_by_key(get_rank).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn struct_definition(path: &ast::Path, sema: &Semantics<RootDatabase>) -> Option<Struct> {
|
|
||||||
match sema.resolve_path(path) {
|
|
||||||
Some(PathResolution::Def(ModuleDef::Adt(Adt::Struct(s)))) => Some(s),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_fields_ranks(path: &ast::Path, ctx: &AssistContext) -> Option<FxHashMap<String, usize>> {
|
fn compute_fields_ranks(path: &ast::Path, ctx: &AssistContext) -> Option<FxHashMap<String, usize>> {
|
||||||
Some(
|
let strukt = match ctx.sema.resolve_path(path) {
|
||||||
struct_definition(path, &ctx.sema)?
|
Some(hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Struct(it)))) => it,
|
||||||
.fields(ctx.db())
|
_ => return None,
|
||||||
.iter()
|
};
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, field)| (field.name(ctx.db()).to_string(), idx))
|
let res = strukt
|
||||||
.collect(),
|
.fields(ctx.db())
|
||||||
)
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(idx, field)| (field.name(ctx.db()).to_string(), idx))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Some(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -118,11 +106,7 @@ mod tests {
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
reorder_fields,
|
reorder_fields,
|
||||||
r#"
|
r#"
|
||||||
struct Foo {
|
struct Foo { foo: i32, bar: i32 }
|
||||||
foo: i32,
|
|
||||||
bar: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
const test: Foo = $0Foo { foo: 0, bar: 0 };
|
const test: Foo = $0Foo { foo: 0, bar: 0 };
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
|
@ -133,8 +117,8 @@ const test: Foo = $0Foo { foo: 0, bar: 0 };
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
reorder_fields,
|
reorder_fields,
|
||||||
r#"
|
r#"
|
||||||
struct Foo {};
|
struct Foo {}
|
||||||
const test: Foo = $0Foo {}
|
const test: Foo = $0Foo {};
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -144,12 +128,12 @@ const test: Foo = $0Foo {}
|
||||||
check_assist(
|
check_assist(
|
||||||
reorder_fields,
|
reorder_fields,
|
||||||
r#"
|
r#"
|
||||||
struct Foo {foo: i32, bar: i32};
|
struct Foo { foo: i32, bar: i32 }
|
||||||
const test: Foo = $0Foo {bar: 0, foo: 1}
|
const test: Foo = $0Foo { bar: 0, foo: 1 };
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
struct Foo {foo: i32, bar: i32};
|
struct Foo { foo: i32, bar: i32 }
|
||||||
const test: Foo = Foo {foo: 1, bar: 0}
|
const test: Foo = Foo { foo: 1, bar: 0 };
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -186,10 +170,7 @@ fn f(f: Foo) -> {
|
||||||
check_assist(
|
check_assist(
|
||||||
reorder_fields,
|
reorder_fields,
|
||||||
r#"
|
r#"
|
||||||
struct Foo {
|
struct Foo { foo: String, bar: String }
|
||||||
foo: String,
|
|
||||||
bar: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn new() -> Foo {
|
fn new() -> Foo {
|
||||||
|
@ -203,10 +184,7 @@ impl Foo {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
struct Foo {
|
struct Foo { foo: String, bar: String }
|
||||||
foo: String,
|
|
||||||
bar: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn new() -> Foo {
|
fn new() -> Foo {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue