]> git.lizzy.rs Git - rust.git/commitdiff
Move field_shorthand to a separate module
authorAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 15 Oct 2020 15:07:53 +0000 (17:07 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 15 Oct 2020 15:10:06 +0000 (17:10 +0200)
crates/ide/src/diagnostics.rs
crates/ide/src/diagnostics/field_shorthand.rs [new file with mode: 0644]

index c36c321f2b5f8f5b46ea99f850ad14339d803d56..1e5ea4617b79baeffd7f95dec978f8009a404987 100644 (file)
@@ -5,6 +5,7 @@
 //! original files. So we need to map the ranges.
 
 mod fixes;
+mod field_shorthand;
 
 use std::cell::RefCell;
 
@@ -15,7 +16,7 @@
 use rustc_hash::FxHashSet;
 use syntax::{
     ast::{self, AstNode},
-    match_ast, SyntaxNode, TextRange, T,
+    SyntaxNode, TextRange, T,
 };
 use text_edit::TextEdit;
 
@@ -80,7 +81,7 @@ pub(crate) fn diagnostics(
 
     for node in parse.tree().syntax().descendants() {
         check_unnecessary_braces_in_use_statement(&mut res, file_id, &node);
-        check_field_shorthand(&mut res, file_id, &node);
+        field_shorthand::check(&mut res, file_id, &node);
     }
     let res = RefCell::new(res);
     let sink_builder = DiagnosticSinkBuilder::new()
@@ -188,100 +189,6 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
     None
 }
 
-fn check_field_shorthand(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) {
-    match_ast! {
-        match node {
-            ast::RecordExpr(it) => check_expr_field_shorthand(acc, file_id, it),
-            ast::RecordPat(it) => check_pat_field_shorthand(acc, file_id, it),
-            _ => ()
-        }
-    };
-}
-
-fn check_expr_field_shorthand(
-    acc: &mut Vec<Diagnostic>,
-    file_id: FileId,
-    record_expr: ast::RecordExpr,
-) {
-    let record_field_list = match record_expr.record_expr_field_list() {
-        Some(it) => it,
-        None => return,
-    };
-    for record_field in record_field_list.fields() {
-        let (name_ref, expr) = match record_field.name_ref().zip(record_field.expr()) {
-            Some(it) => it,
-            None => continue,
-        };
-
-        let field_name = name_ref.syntax().text().to_string();
-        let field_expr = expr.syntax().text().to_string();
-        let field_name_is_tup_index = name_ref.as_tuple_field().is_some();
-        if field_name != field_expr || field_name_is_tup_index {
-            continue;
-        }
-
-        let mut edit_builder = TextEdit::builder();
-        edit_builder.delete(record_field.syntax().text_range());
-        edit_builder.insert(record_field.syntax().text_range().start(), field_name);
-        let edit = edit_builder.finish();
-
-        let field_range = record_field.syntax().text_range();
-        acc.push(Diagnostic {
-            // name: None,
-            range: field_range,
-            message: "Shorthand struct initialization".to_string(),
-            severity: Severity::WeakWarning,
-            fix: Some(Fix::new(
-                "Use struct shorthand initialization",
-                SourceFileEdit { file_id, edit }.into(),
-                field_range,
-            )),
-        });
-    }
-}
-
-fn check_pat_field_shorthand(
-    acc: &mut Vec<Diagnostic>,
-    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};
@@ -295,7 +202,7 @@ mod tests {
     ///  * a diagnostic is produced
     ///  * this diagnostic fix trigger range touches the input cursor position
     ///  * that the contents of the file containing the cursor match `after` after the diagnostic fix is applied
-    fn check_fix(ra_fixture_before: &str, ra_fixture_after: &str) {
+    pub(super) fn check_fix(ra_fixture_before: &str, ra_fixture_after: &str) {
         let after = trim_indent(ra_fixture_after);
 
         let (analysis, file_position) = fixture::position(ra_fixture_before);
@@ -377,7 +284,7 @@ fn check_apply_diagnostic_fix_in_other_file(ra_fixture_before: &str, ra_fixture_
 
     /// Takes a multi-file input fixture with annotated cursor position and checks that no diagnostics
     /// apply to the file containing the cursor.
-    fn check_no_diagnostics(ra_fixture: &str) {
+    pub(crate) fn check_no_diagnostics(ra_fixture: &str) {
         let (analysis, files) = fixture::files(ra_fixture);
         let diagnostics = files
             .into_iter()
@@ -777,104 +684,6 @@ mod a { mod c {} mod d { mod e {} } }
         );
     }
 
-    #[test]
-    fn test_check_expr_field_shorthand() {
-        check_no_diagnostics(
-            r#"
-struct A { a: &'static str }
-fn main() { A { a: "hello" } }
-"#,
-        );
-        check_no_diagnostics(
-            r#"
-struct A(usize);
-fn main() { A { 0: 0 } }
-"#,
-        );
-
-        check_fix(
-            r#"
-struct A { a: &'static str }
-fn main() {
-    let a = "haha";
-    A { a<|>: a }
-}
-"#,
-            r#"
-struct A { a: &'static str }
-fn main() {
-    let a = "haha";
-    A { a }
-}
-"#,
-        );
-
-        check_fix(
-            r#"
-struct A { a: &'static str, b: &'static str }
-fn main() {
-    let a = "haha";
-    let b = "bb";
-    A { a<|>: a, b }
-}
-"#,
-            r#"
-struct A { a: &'static str, b: &'static str }
-fn main() {
-    let a = "haha";
-    let b = "bb";
-    A { a, b }
-}
-"#,
-        );
-    }
-
-    #[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(
diff --git a/crates/ide/src/diagnostics/field_shorthand.rs b/crates/ide/src/diagnostics/field_shorthand.rs
new file mode 100644 (file)
index 0000000..2c4acd7
--- /dev/null
@@ -0,0 +1,206 @@
+//! Suggests shortening `Foo { field: field }` to `Foo { field }` in both
+//! expressions and patterns.
+
+use base_db::FileId;
+use ide_db::source_change::SourceFileEdit;
+use syntax::{ast, match_ast, AstNode, SyntaxNode};
+use text_edit::TextEdit;
+
+use crate::{Diagnostic, Fix, Severity};
+
+pub(super) fn check(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) {
+    match_ast! {
+        match node {
+            ast::RecordExpr(it) => check_expr_field_shorthand(acc, file_id, it),
+            ast::RecordPat(it) => check_pat_field_shorthand(acc, file_id, it),
+            _ => ()
+        }
+    };
+}
+
+fn check_expr_field_shorthand(
+    acc: &mut Vec<Diagnostic>,
+    file_id: FileId,
+    record_expr: ast::RecordExpr,
+) {
+    let record_field_list = match record_expr.record_expr_field_list() {
+        Some(it) => it,
+        None => return,
+    };
+    for record_field in record_field_list.fields() {
+        let (name_ref, expr) = match record_field.name_ref().zip(record_field.expr()) {
+            Some(it) => it,
+            None => continue,
+        };
+
+        let field_name = name_ref.syntax().text().to_string();
+        let field_expr = expr.syntax().text().to_string();
+        let field_name_is_tup_index = name_ref.as_tuple_field().is_some();
+        if field_name != field_expr || field_name_is_tup_index {
+            continue;
+        }
+
+        let mut edit_builder = TextEdit::builder();
+        edit_builder.delete(record_field.syntax().text_range());
+        edit_builder.insert(record_field.syntax().text_range().start(), field_name);
+        let edit = edit_builder.finish();
+
+        let field_range = record_field.syntax().text_range();
+        acc.push(Diagnostic {
+            // name: None,
+            range: field_range,
+            message: "Shorthand struct initialization".to_string(),
+            severity: Severity::WeakWarning,
+            fix: Some(Fix::new(
+                "Use struct shorthand initialization",
+                SourceFileEdit { file_id, edit }.into(),
+                field_range,
+            )),
+        });
+    }
+}
+
+fn check_pat_field_shorthand(
+    acc: &mut Vec<Diagnostic>,
+    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 crate::diagnostics::tests::{check_fix, check_no_diagnostics};
+
+    #[test]
+    fn test_check_expr_field_shorthand() {
+        check_no_diagnostics(
+            r#"
+struct A { a: &'static str }
+fn main() { A { a: "hello" } }
+"#,
+        );
+        check_no_diagnostics(
+            r#"
+struct A(usize);
+fn main() { A { 0: 0 } }
+"#,
+        );
+
+        check_fix(
+            r#"
+struct A { a: &'static str }
+fn main() {
+    let a = "haha";
+    A { a<|>: a }
+}
+"#,
+            r#"
+struct A { a: &'static str }
+fn main() {
+    let a = "haha";
+    A { a }
+}
+"#,
+        );
+
+        check_fix(
+            r#"
+struct A { a: &'static str, b: &'static str }
+fn main() {
+    let a = "haha";
+    let b = "bb";
+    A { a<|>: a, b }
+}
+"#,
+            r#"
+struct A { a: &'static str, b: &'static str }
+fn main() {
+    let a = "haha";
+    let b = "bb";
+    A { a, b }
+}
+"#,
+        );
+    }
+
+    #[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;
+}
+"#,
+        );
+    }
+}