From 1022672af0467edf480f50398989c3f8016ccd10 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 15 Oct 2020 17:03:52 +0200 Subject: Diagnose shorthand in patterns as well --- crates/ide/src/diagnostics.rs | 99 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 5 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index d3d8c86b5..c36c321f2 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs @@ -192,7 +192,8 @@ fn check_field_shorthand(acc: &mut Vec, file_id: FileId, node: &Synt match_ast! { match node { ast::RecordExpr(it) => check_expr_field_shorthand(acc, file_id, it), - _ => None + ast::RecordPat(it) => check_pat_field_shorthand(acc, file_id, it), + _ => () } }; } @@ -200,11 +201,11 @@ fn check_field_shorthand(acc: &mut Vec, file_id: FileId, node: &Synt fn check_expr_field_shorthand( acc: &mut Vec, file_id: FileId, - record_lit: ast::RecordExpr, + record_expr: ast::RecordExpr, ) { - let record_field_list = match record_lit.record_expr_field_list() { + let record_field_list = match record_expr.record_expr_field_list() { Some(it) => it, - None => (), + None => return, }; for record_field in record_field_list.fields() { let (name_ref, expr) = match record_field.name_ref().zip(record_field.expr()) { @@ -239,6 +240,48 @@ fn check_expr_field_shorthand( } } +fn check_pat_field_shorthand( + acc: &mut Vec, + file_id: FileId, + record_pat: ast::RecordPat, +) { + let record_pat_field_list = match record_pat.record_pat_field_list() { + Some(it) => it, + None => return, + }; + for record_pat_field in record_pat_field_list.fields() { + let (name_ref, pat) = match record_pat_field.name_ref().zip(record_pat_field.pat()) { + Some(it) => it, + None => continue, + }; + + let field_name = name_ref.syntax().text().to_string(); + let field_pat = pat.syntax().text().to_string(); + let field_name_is_tup_index = name_ref.as_tuple_field().is_some(); + if field_name != field_pat || field_name_is_tup_index { + continue; + } + + let mut edit_builder = TextEdit::builder(); + edit_builder.delete(record_pat_field.syntax().text_range()); + edit_builder.insert(record_pat_field.syntax().text_range().start(), field_name); + let edit = edit_builder.finish(); + + let field_range = record_pat_field.syntax().text_range(); + acc.push(Diagnostic { + // name: None, + range: field_range, + message: "Shorthand struct pattern".to_string(), + severity: Severity::WeakWarning, + fix: Some(Fix::new( + "Use struct field shorthand", + SourceFileEdit { file_id, edit }.into(), + field_range, + )), + }); + } +} + #[cfg(test)] mod tests { use expect_test::{expect, Expect}; @@ -735,7 +778,7 @@ mod a { } #[test] - fn test_check_struct_shorthand_initialization() { + fn test_check_expr_field_shorthand() { check_no_diagnostics( r#" struct A { a: &'static str } @@ -786,6 +829,52 @@ fn main() { ); } + #[test] + fn test_check_pat_field_shorthand() { + check_no_diagnostics( + r#" +struct A { a: &'static str } +fn f(a: A) { let A { a: hello } = a; } +"#, + ); + check_no_diagnostics( + r#" +struct A(usize); +fn f(a: A) { let A { 0: 0 } = a; } +"#, + ); + + check_fix( + r#" +struct A { a: &'static str } +fn f(a: A) { + let A { a<|>: a } = a; +} +"#, + r#" +struct A { a: &'static str } +fn f(a: A) { + let A { a } = a; +} +"#, + ); + + check_fix( + r#" +struct A { a: &'static str, b: &'static str } +fn f(a: A) { + let A { a<|>: a, b } = a; +} +"#, + r#" +struct A { a: &'static str, b: &'static str } +fn f(a: A) { + let A { a, b } = a; +} +"#, + ); + } + #[test] fn test_add_field_from_usage() { check_fix( -- cgit v1.2.3