Add new lint: unknwon_clippy_lintsg

This commit is contained in:
flip1995 2018-09-10 17:09:15 +02:00 committed by flip1995
parent 62568923d5
commit f6d57862c7
No known key found for this signature in database
GPG Key ID: E8E897A5870E41C2
2 changed files with 87 additions and 7 deletions

View File

@ -12,16 +12,20 @@
use crate::reexport::*;
use crate::utils::{
in_macro, last_line_of_span, match_def_path, opt_def_id, paths, snippet_opt, span_lint, span_lint_and_then,
without_block_comments,
in_macro, last_line_of_span, match_def_path, opt_def_id, paths, snippet_opt, span_lint,
span_lint_and_then, without_block_comments,
};
use crate::rustc::hir::*;
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array};
use if_chain::if_chain;
use crate::rustc::hir::*;
use crate::rustc::lint::{
CheckLintNameResult, LateContext, LateLintPass, LintArray, LintContext, LintPass,
};
use crate::rustc::ty::{self, TyCtxt};
use crate::rustc::{declare_tool_lint, lint_array};
use semver::Version;
use crate::syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
use crate::syntax::ast::{
AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind,
};
use crate::syntax::source_map::Span;
use crate::rustc_errors::Applicability;
@ -138,6 +142,33 @@ declare_clippy_lint! {
"empty line after outer attribute"
}
/// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy
/// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name
/// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase
/// the lint name.
///
/// **Why is this bad?** An lint attribute with a misstyped lint name won't have an effect.
///
/// **Known problems:** None.
///
/// **Example:**
/// Bad:
/// ```rust
/// #![warn(if_not_els)]
/// #![deny(clippy::All)]
/// ```
///
/// Good:
/// ```rust
/// #![warn(if_not_else)]
/// #![deny(clippy::all)]
/// ```
declare_clippy_lint! {
pub UNKNOWN_CLIPPY_LINTS,
style,
"unknown_lints for scoped Clippy lints"
}
#[derive(Copy, Clone)]
pub struct AttrPass;
@ -147,7 +178,8 @@ impl LintPass for AttrPass {
INLINE_ALWAYS,
DEPRECATED_SEMVER,
USELESS_ATTRIBUTE,
EMPTY_LINE_AFTER_OUTER_ATTR
EMPTY_LINE_AFTER_OUTER_ATTR,
UNKNOWN_CLIPPY_LINTS,
)
}
}
@ -155,6 +187,12 @@ impl LintPass for AttrPass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) {
if let Some(ref items) = attr.meta_item_list() {
match &*attr.name().as_str() {
"allow" | "warn" | "deny" | "forbid" => {
check_clippy_lint_names(cx, items);
}
_ => {}
}
if items.is_empty() || attr.name() != "deprecated" {
return;
}
@ -247,6 +285,46 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
}
}
fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &Vec<NestedMetaItem>) {
let lint_store = cx.lints();
for lint in items {
if_chain! {
if let Some(word) = lint.word();
if let Some(tool_name) = word.is_scoped();
if tool_name.as_str() == "clippy";
let name = word.name();
if let CheckLintNameResult::Tool(Err((None, _))) = lint_store.check_lint_name(
&name.as_str(),
Some(tool_name.as_str()),
);
then {
span_lint_and_then(
cx,
UNKNOWN_CLIPPY_LINTS,
lint.span,
&format!("unknwon clippy lint: clippy::{}", name),
|db| {
if name.as_str().chars().any(|c| c.is_uppercase()) {
let name_lower = name.as_str().to_lowercase().to_string();
match lint_store.check_lint_name(
&name_lower,
Some(tool_name.as_str())
) {
CheckLintNameResult::NoLint => {}
_ => {
db.span_suggestion(lint.span,
"lowercase the lint name",
name_lower);
}
}
}
}
);
}
};
}
}
fn is_relevant_item(tcx: TyCtxt<'_, '_, '_>, item: &Item) -> bool {
if let ItemKind::Fn(_, _, _, eid) = item.node {
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)

View File

@ -533,6 +533,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
assign_ops::ASSIGN_OP_PATTERN,
assign_ops::MISREFACTORED_ASSIGN_OP,
attrs::DEPRECATED_SEMVER,
attrs::UNKNOWN_CLIPPY_LINTS,
attrs::USELESS_ATTRIBUTE,
bit_mask::BAD_BIT_MASK,
bit_mask::INEFFECTIVE_BIT_MASK,
@ -749,6 +750,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
reg.register_lint_group("clippy::style", Some("clippy_style"), vec![
assign_ops::ASSIGN_OP_PATTERN,
attrs::UNKNOWN_CLIPPY_LINTS,
bit_mask::VERBOSE_BIT_MASK,
blacklisted_name::BLACKLISTED_NAME,
block_in_if_condition::BLOCK_IN_IF_CONDITION_EXPR,