about summary refs log tree commit diff
path: root/clippy_dev/src/lib.rs
diff options
context:
space:
mode:
authorPhilipp Hansch <dev@phansch.net>2018-07-17 22:50:17 +0200
committerPhilipp Hansch <dev@phansch.net>2018-09-03 22:18:51 +0200
commit35f100b4f9a055a98973f2a2ac2e1eb5c5cfacff (patch)
tree35586d5175d1af3ffe1b93717fad415a42c0b4d2 /clippy_dev/src/lib.rs
parent2b7a5304f6b54b52b307b90d3401d691ed27b956 (diff)
downloadrust-35f100b4f9a055a98973f2a2ac2e1eb5c5cfacff.tar.gz
rust-35f100b4f9a055a98973f2a2ac2e1eb5c5cfacff.zip
update_lints rewrite: Add structure and --print-only
Diffstat (limited to 'clippy_dev/src/lib.rs')
-rw-r--r--clippy_dev/src/lib.rs144
1 files changed, 144 insertions, 0 deletions
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
new file mode 100644
index 00000000000..2a86de9cbaa
--- /dev/null
+++ b/clippy_dev/src/lib.rs
@@ -0,0 +1,144 @@
+extern crate regex;
+#[macro_use]
+extern crate lazy_static;
+
+use regex::Regex;
+use std::ffi::OsStr;
+use std::fs;
+use std::io::prelude::*;
+
+lazy_static! {
+    static ref DEC_CLIPPY_LINT_RE: Regex = Regex::new(r#"declare_clippy_lint!\s*[\{(]\s*pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*(?P<cat>[a-z_]+)\s*,\s*"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]"#).unwrap();
+    static ref DEC_DEPRECATED_LINT_RE: Regex = Regex::new(r#"declare_deprecated_lint!\s*[{(]\s*pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]"#).unwrap();
+    static ref NL_ESCAPE_RE: Regex = Regex::new(r#"\\\n\s*"#).unwrap();
+    pub static ref DOCS_LINK: String = "https://rust-lang-nursery.github.io/rust-clippy/master/index.html".to_string();
+}
+
+#[derive(Clone, PartialEq, Debug)]
+pub struct Lint {
+    pub name: String,
+    pub group: String,
+    pub desc: String,
+    pub deprecation: Option<String>,
+    pub module: String,
+}
+
+impl Lint {
+    pub fn new(name: &str, group: &str, desc: &str, deprecation: Option<&str>, module: &str) -> Lint {
+        Lint {
+            name: name.to_lowercase(),
+            group: group.to_string(),
+            desc: NL_ESCAPE_RE.replace(&desc.replace("\\\"", "\""), "").to_string(),
+            deprecation: deprecation.map(|d| d.to_string()),
+            module: module.to_string(),
+        }
+    }
+
+    pub fn active_lints(lints: &[Lint]) -> Vec<Lint> {
+        lints.iter().filter(|l| l.deprecation.is_none()).cloned().collect::<Vec<Lint>>()
+    }
+
+    pub fn in_lint_group(group: &str, lints: &[Lint]) -> Vec<Lint> {
+        lints.iter().filter(|l| l.group == group).cloned().collect::<Vec<Lint>>()
+    }
+}
+
+pub fn collect_all() -> Vec<Lint> {
+    let mut lints = vec![];
+    for direntry in lint_files() {
+        lints.append(&mut collect_from_file(&direntry));
+    }
+    lints
+}
+
+fn collect_from_file(direntry: &fs::DirEntry) -> Vec<Lint> {
+    let mut file = fs::File::open(direntry.path()).unwrap();
+    let mut content = String::new();
+    file.read_to_string(&mut content).unwrap();
+    parse_contents(&content, direntry.path().file_stem().unwrap().to_str().unwrap())
+}
+
+fn parse_contents(content: &str, filename: &str) -> Vec<Lint> {
+    let mut lints: Vec<Lint> = DEC_CLIPPY_LINT_RE
+        .captures_iter(&content)
+        .map(|m| Lint::new(&m["name"], &m["cat"], &m["desc"], None, filename))
+        .collect();
+    let mut deprecated = DEC_DEPRECATED_LINT_RE
+        .captures_iter(&content)
+        .map(|m| Lint::new( &m["name"], "Deprecated", &m["desc"], Some(&m["desc"]), filename))
+        .collect();
+    lints.append(&mut deprecated);
+    lints
+}
+
+/// Collects all .rs files in the `clippy_lints/src` directory
+fn lint_files() -> Vec<fs::DirEntry> {
+    let paths = fs::read_dir("../clippy_lints/src").unwrap();
+    paths
+        .filter_map(|f| f.ok())
+        .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
+        .collect::<Vec<fs::DirEntry>>()
+}
+
+#[test]
+fn test_parse_contents() {
+    let result = parse_contents(
+        r#"
+declare_clippy_lint! {
+    pub PTR_ARG,
+    style,
+    "really long \
+     text"
+}
+
+declare_clippy_lint!{
+    pub DOC_MARKDOWN,
+    pedantic,
+    "single line"
+}
+
+/// some doc comment
+declare_deprecated_lint! {
+    pub SHOULD_ASSERT_EQ,
+    "`assert!()` will be more flexible with RFC 2011"
+}
+    "#,
+    "module_name");
+
+    let expected = vec![
+        Lint::new("ptr_arg", "style", "really long text", None, "module_name"),
+        Lint::new("doc_markdown", "pedantic", "single line", None, "module_name"),
+        Lint::new(
+            "should_assert_eq",
+            "Deprecated",
+            "`assert!()` will be more flexible with RFC 2011",
+            Some("`assert!()` will be more flexible with RFC 2011"),
+            "module_name"
+        ),
+    ];
+    assert_eq!(expected, result);
+}
+
+#[test]
+fn test_active_lints() {
+    let lints = vec![
+        Lint::new("should_assert_eq", "Deprecated", "abc", Some("Reason"), "module_name"),
+        Lint::new("should_assert_eq2", "Not Deprecated", "abc", None, "module_name")
+    ];
+    let expected = vec![
+        Lint::new("should_assert_eq2", "Not Deprecated", "abc", None, "module_name")
+    ];
+    assert_eq!(expected, Lint::active_lints(&lints));
+}
+
+#[test]
+fn test_in_lint_group() {
+    let lints = vec![
+        Lint::new("ptr_arg", "style", "really long text", None, "module_name"),
+        Lint::new("doc_markdown", "pedantic", "single line", None, "module_name"),
+    ];
+    let expected = vec![
+        Lint::new("ptr_arg", "style", "really long text", None, "module_name")
+    ];
+    assert_eq!(expected, Lint::in_lint_group("style", &lints));
+}