aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/diagnostics/field_shorthand.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/diagnostics/field_shorthand.rs')
-rw-r--r--crates/ide/src/diagnostics/field_shorthand.rs200
1 files changed, 0 insertions, 200 deletions
diff --git a/crates/ide/src/diagnostics/field_shorthand.rs b/crates/ide/src/diagnostics/field_shorthand.rs
deleted file mode 100644
index 01bd2dba6..000000000
--- a/crates/ide/src/diagnostics/field_shorthand.rs
+++ /dev/null
@@ -1,200 +0,0 @@
1//! Suggests shortening `Foo { field: field }` to `Foo { field }` in both
2//! expressions and patterns.
3
4use ide_db::{base_db::FileId, source_change::SourceChange};
5use syntax::{ast, match_ast, AstNode, SyntaxNode};
6use text_edit::TextEdit;
7
8use crate::{diagnostics::fix, Diagnostic};
9
10pub(super) fn check(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) {
11 match_ast! {
12 match node {
13 ast::RecordExpr(it) => check_expr_field_shorthand(acc, file_id, it),
14 ast::RecordPat(it) => check_pat_field_shorthand(acc, file_id, it),
15 _ => ()
16 }
17 };
18}
19
20fn check_expr_field_shorthand(
21 acc: &mut Vec<Diagnostic>,
22 file_id: FileId,
23 record_expr: ast::RecordExpr,
24) {
25 let record_field_list = match record_expr.record_expr_field_list() {
26 Some(it) => it,
27 None => return,
28 };
29 for record_field in record_field_list.fields() {
30 let (name_ref, expr) = match record_field.name_ref().zip(record_field.expr()) {
31 Some(it) => it,
32 None => continue,
33 };
34
35 let field_name = name_ref.syntax().text().to_string();
36 let field_expr = expr.syntax().text().to_string();
37 let field_name_is_tup_index = name_ref.as_tuple_field().is_some();
38 if field_name != field_expr || field_name_is_tup_index {
39 continue;
40 }
41
42 let mut edit_builder = TextEdit::builder();
43 edit_builder.delete(record_field.syntax().text_range());
44 edit_builder.insert(record_field.syntax().text_range().start(), field_name);
45 let edit = edit_builder.finish();
46
47 let field_range = record_field.syntax().text_range();
48 acc.push(
49 Diagnostic::hint(field_range, "Shorthand struct initialization".to_string())
50 .with_fixes(Some(vec![fix(
51 "use_expr_field_shorthand",
52 "Use struct shorthand initialization",
53 SourceChange::from_text_edit(file_id, edit),
54 field_range,
55 )])),
56 );
57 }
58}
59
60fn check_pat_field_shorthand(
61 acc: &mut Vec<Diagnostic>,
62 file_id: FileId,
63 record_pat: ast::RecordPat,
64) {
65 let record_pat_field_list = match record_pat.record_pat_field_list() {
66 Some(it) => it,
67 None => return,
68 };
69 for record_pat_field in record_pat_field_list.fields() {
70 let (name_ref, pat) = match record_pat_field.name_ref().zip(record_pat_field.pat()) {
71 Some(it) => it,
72 None => continue,
73 };
74
75 let field_name = name_ref.syntax().text().to_string();
76 let field_pat = pat.syntax().text().to_string();
77 let field_name_is_tup_index = name_ref.as_tuple_field().is_some();
78 if field_name != field_pat || field_name_is_tup_index {
79 continue;
80 }
81
82 let mut edit_builder = TextEdit::builder();
83 edit_builder.delete(record_pat_field.syntax().text_range());
84 edit_builder.insert(record_pat_field.syntax().text_range().start(), field_name);
85 let edit = edit_builder.finish();
86
87 let field_range = record_pat_field.syntax().text_range();
88 acc.push(Diagnostic::hint(field_range, "Shorthand struct pattern".to_string()).with_fixes(
89 Some(vec![fix(
90 "use_pat_field_shorthand",
91 "Use struct field shorthand",
92 SourceChange::from_text_edit(file_id, edit),
93 field_range,
94 )]),
95 ));
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use crate::diagnostics::tests::{check_fix, check_no_diagnostics};
102
103 #[test]
104 fn test_check_expr_field_shorthand() {
105 check_no_diagnostics(
106 r#"
107struct A { a: &'static str }
108fn main() { A { a: "hello" } }
109"#,
110 );
111 check_no_diagnostics(
112 r#"
113struct A(usize);
114fn main() { A { 0: 0 } }
115"#,
116 );
117
118 check_fix(
119 r#"
120struct A { a: &'static str }
121fn main() {
122 let a = "haha";
123 A { a$0: a }
124}
125"#,
126 r#"
127struct A { a: &'static str }
128fn main() {
129 let a = "haha";
130 A { a }
131}
132"#,
133 );
134
135 check_fix(
136 r#"
137struct A { a: &'static str, b: &'static str }
138fn main() {
139 let a = "haha";
140 let b = "bb";
141 A { a$0: a, b }
142}
143"#,
144 r#"
145struct A { a: &'static str, b: &'static str }
146fn main() {
147 let a = "haha";
148 let b = "bb";
149 A { a, b }
150}
151"#,
152 );
153 }
154
155 #[test]
156 fn test_check_pat_field_shorthand() {
157 check_no_diagnostics(
158 r#"
159struct A { a: &'static str }
160fn f(a: A) { let A { a: hello } = a; }
161"#,
162 );
163 check_no_diagnostics(
164 r#"
165struct A(usize);
166fn f(a: A) { let A { 0: 0 } = a; }
167"#,
168 );
169
170 check_fix(
171 r#"
172struct A { a: &'static str }
173fn f(a: A) {
174 let A { a$0: a } = a;
175}
176"#,
177 r#"
178struct A { a: &'static str }
179fn f(a: A) {
180 let A { a } = a;
181}
182"#,
183 );
184
185 check_fix(
186 r#"
187struct A { a: &'static str, b: &'static str }
188fn f(a: A) {
189 let A { a$0: a, b } = a;
190}
191"#,
192 r#"
193struct A { a: &'static str, b: &'static str }
194fn f(a: A) {
195 let A { a, b } = a;
196}
197"#,
198 );
199 }
200}