diff options
| author | llogiq <bogusandre@gmail.com> | 2016-01-09 02:05:43 +0100 |
|---|---|---|
| committer | llogiq <bogusandre@gmail.com> | 2016-01-09 02:05:43 +0100 |
| commit | 37707b5a34752e950ee09e9d0e5effb1f481fff1 (patch) | |
| tree | 9a0ccb9432cb4fa537d14573313e371beb2ee97e /src | |
| parent | a21108a2963c63310d9c5b452e7faf3e622c47de (diff) | |
| download | rust-37707b5a34752e950ee09e9d0e5effb1f481fff1.tar.gz rust-37707b5a34752e950ee09e9d0e5effb1f481fff1.zip | |
added semver lint
Diffstat (limited to 'src')
| -rw-r--r-- | src/attrs.rs | 45 | ||||
| -rw-r--r-- | src/lib.rs | 4 |
2 files changed, 47 insertions, 2 deletions
diff --git a/src/attrs.rs b/src/attrs.rs index ec2cfcb0efc..853e2ab5910 100644 --- a/src/attrs.rs +++ b/src/attrs.rs @@ -3,9 +3,10 @@ use rustc::lint::*; use rustc_front::hir::*; use reexport::*; +use semver::Version; use syntax::codemap::Span; use syntax::attr::*; -use syntax::ast::{Attribute, MetaList, MetaWord}; +use syntax::ast::{Attribute, Lit, Lit_, MetaList, MetaWord, MetaNameValue}; use utils::{in_macro, match_path, span_lint, BEGIN_UNWIND}; /// **What it does:** This lint `Warn`s on items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics. @@ -24,17 +25,45 @@ use utils::{in_macro, match_path, span_lint, BEGIN_UNWIND}; declare_lint! { pub INLINE_ALWAYS, Warn, "`#[inline(always)]` is a bad idea in most cases" } +/// **What it does:** This lint `Warn`s on `#[deprecated]` annotations with a `since` field that is not a valid semantic version.. +/// +/// **Why is this bad?** For checking the version of the deprecation, it must be valid semver. Failing that, the contained information is useless. +/// +/// **Known problems:** None +/// +/// **Example:** +/// ``` +/// #[deprecated(since = "forever")] +/// fn something_else(..) { ... } +/// ``` +declare_lint! { pub DEPRECATED_SEMVER, Warn, + "`Warn` on `#[deprecated(since = \"x\")]` where x is not semver" } #[derive(Copy,Clone)] pub struct AttrPass; impl LintPass for AttrPass { fn get_lints(&self) -> LintArray { - lint_array!(INLINE_ALWAYS) + lint_array!(INLINE_ALWAYS, DEPRECATED_SEMVER) } } impl LateLintPass for AttrPass { + fn check_attribute(&mut self, cx: &LateContext, attr: &Attribute) { + if let MetaList(ref name, ref items) = attr.node.value.node { + if items.is_empty() || name != &"deprecated" { + return; + } + for ref item in items { + if let MetaNameValue(ref name, ref lit) = item.node { + if name == &"since" { + check_semver(cx, item.span, lit); + } + } + } + } + } + fn check_item(&mut self, cx: &LateContext, item: &Item) { if is_relevant_item(item) { check_attrs(cx, item.span, &item.name, &item.attrs) @@ -128,3 +157,15 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) { } } } + +fn check_semver(cx: &LateContext, span: Span, lit: &Lit) { + if let Lit_::LitStr(ref is, _) = lit.node { + if Version::parse(&*is).is_ok() { + return; + } + } + span_lint(cx, + DEPRECATED_SEMVER, + span, + "the since field must contain a semver-compliant version"); +} diff --git a/src/lib.rs b/src/lib.rs index 45f47fe3d63..f8db15605ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,9 @@ extern crate collections; // for unicode nfc normalization extern crate unicode_normalization; +// for semver check in attrs.rs +extern crate semver; + extern crate rustc_plugin; use rustc_plugin::Registry; @@ -156,6 +159,7 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_lint_group("clippy", vec