Skip to content

Commit 270bcfd

Browse files
committed
Avoid adding a RecordFieldPat variant to the Pat enum
1 parent 21443f1 commit 270bcfd

File tree

4 files changed

+48
-49
lines changed

4 files changed

+48
-49
lines changed

crates/ra_assists/src/handlers/reorder_fields.rs

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,79 @@ use itertools::Itertools;
44

55
use hir::{Adt, ModuleDef, PathResolution, Semantics, Struct};
66
use ra_ide_db::RootDatabase;
7-
use ra_syntax::ast::{Name, Pat};
87
use ra_syntax::{
9-
ast,
10-
ast::{Path, RecordField, RecordLit, RecordPat},
11-
AstNode,
8+
algo, ast,
9+
ast::{Name, Path, RecordLit, RecordPat},
10+
AstNode, SyntaxKind, SyntaxNode,
1211
};
1312

1413
use crate::{
1514
assist_ctx::{Assist, AssistCtx},
1615
AssistId,
1716
};
17+
use ra_syntax::ast::{Expr, NameRef};
1818

1919
pub(crate) fn reorder_fields(ctx: AssistCtx) -> Option<Assist> {
20-
reorder_struct(ctx.clone()).or_else(|| reorder_struct_pat(ctx))
20+
reorder::<RecordLit>(ctx.clone()).or_else(|| reorder::<RecordPat>(ctx))
2121
}
2222

23-
fn reorder_struct(ctx: AssistCtx) -> Option<Assist> {
24-
let record: RecordLit = ctx.find_node_at_offset()?;
25-
reorder(ctx, &record, &record.path()?, field_name)
26-
}
27-
28-
fn field_name(r: &RecordField) -> String {
29-
r.name_ref()
30-
.map(|name| name.syntax().text().to_string())
31-
.or_else(|| r.expr().map(|e| e.syntax().text().to_string()))
32-
.unwrap_or_default()
33-
}
34-
35-
fn reorder_struct_pat(ctx: AssistCtx) -> Option<Assist> {
36-
let record: RecordPat = ctx.find_node_at_offset()?;
37-
reorder(ctx, &record, &record.path()?, field_pat_name)
38-
}
23+
fn reorder<R: AstNode>(ctx: AssistCtx) -> Option<Assist> {
24+
let record = ctx.find_node_at_offset::<R>()?;
25+
let path = record.syntax().children().find_map(Path::cast)?;
3926

40-
fn field_pat_name(field: &Pat) -> String {
41-
field.syntax().children().find_map(Name::cast).map(|n| n.to_string()).unwrap_or_default()
42-
}
27+
let ranks = compute_fields_ranks(&path, &ctx)?;
4328

44-
fn reorder<R: AstNode, F: AstNode + Eq + Clone>(
45-
ctx: AssistCtx,
46-
record: &R,
47-
path: &Path,
48-
field_name: fn(&F) -> String,
49-
) -> Option<Assist> {
50-
let ranks = compute_fields_ranks(path, &ctx)?;
51-
let fields: Vec<F> = get_fields(record);
52-
let sorted_fields: Vec<F> =
53-
sort_by_rank(&fields, |f| *ranks.get(&field_name(f)).unwrap_or(&usize::max_value()));
29+
let fields = get_fields(&record.syntax());
30+
let sorted_fields = sorted_by_rank(&fields, |node| {
31+
*ranks.get(&get_field_name(node)).unwrap_or(&usize::max_value())
32+
});
5433

5534
if sorted_fields == fields {
5635
return None;
5736
}
5837

5938
ctx.add_assist(AssistId("reorder_fields"), "Reorder record fields", |edit| {
60-
for (old, new) in fields.into_iter().zip(sorted_fields) {
61-
edit.replace_ast(old, new);
39+
for (old, new) in fields.iter().zip(&sorted_fields) {
40+
algo::diff(old, new).into_text_edit(edit.text_edit_builder());
6241
}
6342
edit.target(record.syntax().text_range())
6443
})
6544
}
6645

67-
fn get_fields<R: AstNode, F: AstNode>(record: &R) -> Vec<F> {
68-
record.syntax().children().flat_map(|n1| n1.children()).filter_map(|n3| F::cast(n3)).collect()
46+
fn get_fields_kind(node: &SyntaxNode) -> Vec<SyntaxKind> {
47+
use SyntaxKind::*;
48+
match node.kind() {
49+
RECORD_LIT => vec![RECORD_FIELD],
50+
RECORD_PAT => vec![RECORD_FIELD_PAT, BIND_PAT],
51+
_ => vec![],
52+
}
53+
}
54+
55+
fn get_field_name(node: &SyntaxNode) -> String {
56+
use SyntaxKind::*;
57+
match node.kind() {
58+
RECORD_FIELD => {
59+
if let Some(name) = node.children().find_map(NameRef::cast) {
60+
return name.to_string();
61+
}
62+
node.children().find_map(Expr::cast).map(|expr| expr.to_string()).unwrap_or_default()
63+
}
64+
BIND_PAT | RECORD_FIELD_PAT => {
65+
node.children().find_map(Name::cast).map(|n| n.to_string()).unwrap_or_default()
66+
}
67+
_ => String::new(),
68+
}
69+
}
70+
71+
fn get_fields(record: &SyntaxNode) -> Vec<SyntaxNode> {
72+
let kinds = get_fields_kind(record);
73+
record.children().flat_map(|n| n.children()).filter(|n| kinds.contains(&n.kind())).collect()
6974
}
7075

71-
fn sort_by_rank<F: AstNode + Clone>(fields: &[F], get_rank: impl FnMut(&F) -> usize) -> Vec<F> {
76+
fn sorted_by_rank(
77+
fields: &[SyntaxNode],
78+
get_rank: impl Fn(&SyntaxNode) -> usize,
79+
) -> Vec<SyntaxNode> {
7280
fields.iter().cloned().sorted_by_key(get_rank).collect()
7381
}
7482

crates/ra_hir_def/src/body/lower.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,6 @@ impl ExprCollector<'_> {
691691
}
692692
// FIXME: implement
693693
ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
694-
// FIXME: implement
695-
ast::Pat::RecordFieldPat(_) => Pat::Missing,
696694
};
697695
let ptr = AstPtr::new(&pat);
698696
self.alloc_pat(pattern, Either::Left(ptr))

crates/ra_syntax/src/ast/generated/nodes.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3256,7 +3256,6 @@ pub enum Pat {
32563256
RangePat(RangePat),
32573257
LiteralPat(LiteralPat),
32583258
MacroPat(MacroPat),
3259-
RecordFieldPat(RecordFieldPat),
32603259
}
32613260
impl From<OrPat> for Pat {
32623261
fn from(node: OrPat) -> Pat { Pat::OrPat(node) }
@@ -3303,15 +3302,12 @@ impl From<LiteralPat> for Pat {
33033302
impl From<MacroPat> for Pat {
33043303
fn from(node: MacroPat) -> Pat { Pat::MacroPat(node) }
33053304
}
3306-
impl From<RecordFieldPat> for Pat {
3307-
fn from(node: RecordFieldPat) -> Pat { Pat::RecordFieldPat(node) }
3308-
}
33093305
impl AstNode for Pat {
33103306
fn can_cast(kind: SyntaxKind) -> bool {
33113307
match kind {
33123308
OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT
33133309
| PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT
3314-
| LITERAL_PAT | MACRO_PAT | RECORD_FIELD_PAT => true,
3310+
| LITERAL_PAT | MACRO_PAT => true,
33153311
_ => false,
33163312
}
33173313
}
@@ -3332,7 +3328,6 @@ impl AstNode for Pat {
33323328
RANGE_PAT => Pat::RangePat(RangePat { syntax }),
33333329
LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }),
33343330
MACRO_PAT => Pat::MacroPat(MacroPat { syntax }),
3335-
RECORD_FIELD_PAT => Pat::RecordFieldPat(RecordFieldPat { syntax }),
33363331
_ => return None,
33373332
};
33383333
Some(res)
@@ -3354,7 +3349,6 @@ impl AstNode for Pat {
33543349
Pat::RangePat(it) => &it.syntax,
33553350
Pat::LiteralPat(it) => &it.syntax,
33563351
Pat::MacroPat(it) => &it.syntax,
3357-
Pat::RecordFieldPat(it) => &it.syntax,
33583352
}
33593353
}
33603354
}

xtask/src/ast_src.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,6 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
741741
RangePat,
742742
LiteralPat,
743743
MacroPat,
744-
RecordFieldPat,
745744
}
746745

747746
enum RecordInnerPat {

0 commit comments

Comments
 (0)