Metadata collection monster eating deprecated lints

This commit is contained in:
xFrednet 2021-05-08 13:29:59 +02:00
parent 65951c969f
commit d849e9586e
3 changed files with 62 additions and 21 deletions

View File

@ -1,6 +1,13 @@
/// This struct fakes the `Lint` declaration that is usually created by `declare_lint!`. This
/// enables the simple extraction of the metadata without changing the current depreciation
/// declaration.
pub struct ClippyDeprecatedLint;
macro_rules! declare_deprecated_lint {
(pub $name: ident, $_reason: expr) => {
declare_lint!(pub $name, Allow, "deprecated lint")
{ $(#[$attr:meta])* pub $name: ident, $_reason: expr} => {
$(#[$attr])*
#[allow(dead_code)]
pub static $name: ClippyDeprecatedLint = ClippyDeprecatedLint {};
}
}

View File

@ -162,6 +162,8 @@ macro_rules! extract_msrv_attr {
mod consts;
#[macro_use]
mod utils;
#[cfg(feature = "metadata-collector-lint")]
mod deprecated_lints;
// begin lints modules, do not remove this comment, its used in `update_lints`
mod absurd_extreme_comparisons;

View File

@ -28,7 +28,7 @@ use std::path::Path;
use crate::utils::internal_lints::is_lint_ref_type;
use clippy_utils::{
diagnostics::span_lint, last_path_segment, match_function_call, match_path, paths, ty::match_type,
diagnostics::span_lint, last_path_segment, match_def_path, match_function_call, match_path, paths, ty::match_type,
ty::walk_ptrs_ty_depth,
};
@ -41,6 +41,8 @@ const BLACK_LISTED_LINTS: [&str; 3] = ["lint_author", "deep_code_inspection", "i
const IGNORED_LINT_GROUPS: [&str; 1] = ["clippy::all"];
/// Lints within this group will be excluded from the collection
const EXCLUDED_LINT_GROUPS: [&str; 1] = ["clippy::internal"];
/// Collected deprecated lint will be assigned to this group in the JSON output
const DEPRECATED_LINT_GROUP_STR: &str = "DEPRECATED";
const LINT_EMISSION_FUNCTIONS: [&[&str]; 7] = [
&["clippy_utils", "diagnostics", "span_lint"],
@ -66,6 +68,7 @@ const SUGGESTION_FUNCTIONS: [&[&str]; 2] = [
&["clippy_utils", "diagnostics", "multispan_sugg"],
&["clippy_utils", "diagnostics", "multispan_sugg_with_applicability"],
];
const DEPRECATED_LINT_TYPE: [&str; 3] = ["clippy_lints", "deprecated_lints", "ClippyDeprecatedLint"];
/// The index of the applicability name of `paths::APPLICABILITY_VALUES`
const APPLICABILITY_NAME_INDEX: usize = 2;
@ -225,23 +228,42 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
/// }
/// ```
fn check_item(&mut self, cx: &LateContext<'hir>, item: &'hir Item<'_>) {
if_chain! {
// item validation
if let ItemKind::Static(ref ty, Mutability::Not, _) = item.kind;
if is_lint_ref_type(cx, ty);
// blacklist check
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
// metadata extraction
if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
if let Some(docs) = extract_attr_docs_or_lint(cx, item);
then {
self.lints.push(LintMetadata::new(
lint_name,
SerializableSpan::from_item(cx, item),
group,
docs,
));
if let ItemKind::Static(ref ty, Mutability::Not, _) = item.kind {
// Normal lint
if_chain! {
// item validation
if is_lint_ref_type(cx, ty);
// blacklist check
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
// metadata extraction
if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
if let Some(docs) = extract_attr_docs_or_lint(cx, item);
then {
self.lints.push(LintMetadata::new(
lint_name,
SerializableSpan::from_item(cx, item),
group,
docs,
));
}
}
if_chain! {
if is_deprecated_lint(cx, ty);
// blacklist check
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
// Metadata the little we can get from a deprecated lint
if let Some(docs) = extract_attr_docs_or_lint(cx, item);
then {
self.lints.push(LintMetadata::new(
lint_name,
SerializableSpan::from_item(cx, item),
DEPRECATED_LINT_GROUP_STR.to_string(),
docs,
));
}
}
}
}
@ -268,7 +290,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
// - src/misc.rs:734:9
// - src/methods/mod.rs:3545:13
// - src/methods/mod.rs:3496:13
// We are basically unable to resolve the lint name it self.
// We are basically unable to resolve the lint name itself.
return;
}
@ -347,6 +369,16 @@ fn get_lint_group(cx: &LateContext<'_>, lint_id: LintId) -> Option<String> {
None
}
fn is_deprecated_lint(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
if let hir::TyKind::Path(ref path) = ty.kind {
if let hir::def::Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, ty.hir_id) {
return match_def_path(cx, def_id, &DEPRECATED_LINT_TYPE);
}
}
false
}
// ==================================================================
// Lint emission
// ==================================================================