diff options
| author | Philipp Hansch <dev@phansch.net> | 2018-07-17 22:50:17 +0200 |
|---|---|---|
| committer | Philipp Hansch <dev@phansch.net> | 2018-09-03 22:18:51 +0200 |
| commit | 35f100b4f9a055a98973f2a2ac2e1eb5c5cfacff (patch) | |
| tree | 35586d5175d1af3ffe1b93717fad415a42c0b4d2 /clippy_dev/src/lib.rs | |
| parent | 2b7a5304f6b54b52b307b90d3401d691ed27b956 (diff) | |
| download | rust-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.rs | 144 |
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)); +} |
