mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 05:33:27 +00:00
Use configuration in the TYPE_COMPLEXITY
lint
This commit is contained in:
parent
29c0c2bb09
commit
1841804d43
2 changed files with 46 additions and 34 deletions
|
@ -168,7 +168,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
reg.register_late_lint_pass(box entry::HashMapLint);
|
||||
reg.register_late_lint_pass(box ranges::StepByZero);
|
||||
reg.register_late_lint_pass(box types::CastPass);
|
||||
reg.register_late_lint_pass(box types::TypeComplexityPass);
|
||||
reg.register_late_lint_pass(box types::TypeComplexityPass::new(conf.type_complexity_threshold));
|
||||
reg.register_late_lint_pass(box matches::MatchPass);
|
||||
reg.register_late_lint_pass(box misc::PatternPass);
|
||||
reg.register_late_lint_pass(box minmax::MinMaxPass);
|
||||
|
|
78
src/types.rs
78
src/types.rs
|
@ -417,7 +417,17 @@ declare_lint! {
|
|||
}
|
||||
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub struct TypeComplexityPass;
|
||||
pub struct TypeComplexityPass {
|
||||
threshold: u64,
|
||||
}
|
||||
|
||||
impl TypeComplexityPass {
|
||||
pub fn new(threshold: u64) -> Self {
|
||||
TypeComplexityPass {
|
||||
threshold: threshold
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LintPass for TypeComplexityPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
|
@ -427,18 +437,18 @@ impl LintPass for TypeComplexityPass {
|
|||
|
||||
impl LateLintPass for TypeComplexityPass {
|
||||
fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
|
||||
check_fndecl(cx, decl);
|
||||
self.check_fndecl(cx, decl);
|
||||
}
|
||||
|
||||
fn check_struct_field(&mut self, cx: &LateContext, field: &StructField) {
|
||||
// enum variants are also struct fields now
|
||||
check_type(cx, &field.ty);
|
||||
self.check_type(cx, &field.ty);
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
match item.node {
|
||||
ItemStatic(ref ty, _, _) |
|
||||
ItemConst(ref ty, _) => check_type(cx, ty),
|
||||
ItemConst(ref ty, _) => self.check_type(cx, ty),
|
||||
// functions, enums, structs, impls and traits are covered
|
||||
_ => (),
|
||||
}
|
||||
|
@ -447,8 +457,8 @@ impl LateLintPass for TypeComplexityPass {
|
|||
fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
|
||||
match item.node {
|
||||
ConstTraitItem(ref ty, _) |
|
||||
TypeTraitItem(_, Some(ref ty)) => check_type(cx, ty),
|
||||
MethodTraitItem(MethodSig { ref decl, .. }, None) => check_fndecl(cx, decl),
|
||||
TypeTraitItem(_, Some(ref ty)) => self.check_type(cx, ty),
|
||||
MethodTraitItem(MethodSig { ref decl, .. }, None) => self.check_fndecl(cx, decl),
|
||||
// methods with default impl are covered by check_fn
|
||||
_ => (),
|
||||
}
|
||||
|
@ -457,7 +467,7 @@ impl LateLintPass for TypeComplexityPass {
|
|||
fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
|
||||
match item.node {
|
||||
ImplItemKind::Const(ref ty, _) |
|
||||
ImplItemKind::Type(ref ty) => check_type(cx, ty),
|
||||
ImplItemKind::Type(ref ty) => self.check_type(cx, ty),
|
||||
// methods are covered by check_fn
|
||||
_ => (),
|
||||
}
|
||||
|
@ -465,47 +475,49 @@ impl LateLintPass for TypeComplexityPass {
|
|||
|
||||
fn check_local(&mut self, cx: &LateContext, local: &Local) {
|
||||
if let Some(ref ty) = local.ty {
|
||||
check_type(cx, ty);
|
||||
self.check_type(cx, ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fndecl(cx: &LateContext, decl: &FnDecl) {
|
||||
for arg in &decl.inputs {
|
||||
check_type(cx, &arg.ty);
|
||||
impl TypeComplexityPass {
|
||||
fn check_fndecl(&self, cx: &LateContext, decl: &FnDecl) {
|
||||
for arg in &decl.inputs {
|
||||
self.check_type(cx, &arg.ty);
|
||||
}
|
||||
if let Return(ref ty) = decl.output {
|
||||
self.check_type(cx, ty);
|
||||
}
|
||||
}
|
||||
if let Return(ref ty) = decl.output {
|
||||
check_type(cx, ty);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_type(cx: &LateContext, ty: &Ty) {
|
||||
if in_macro(cx, ty.span) {
|
||||
return;
|
||||
}
|
||||
let score = {
|
||||
let mut visitor = TypeComplexityVisitor {
|
||||
score: 0,
|
||||
nest: 1,
|
||||
fn check_type(&self, cx: &LateContext, ty: &Ty) {
|
||||
if in_macro(cx, ty.span) {
|
||||
return;
|
||||
}
|
||||
let score = {
|
||||
let mut visitor = TypeComplexityVisitor {
|
||||
score: 0,
|
||||
nest: 1,
|
||||
};
|
||||
visitor.visit_ty(ty);
|
||||
visitor.score
|
||||
};
|
||||
visitor.visit_ty(ty);
|
||||
visitor.score
|
||||
};
|
||||
|
||||
if score > 250 {
|
||||
span_lint(cx,
|
||||
TYPE_COMPLEXITY,
|
||||
ty.span,
|
||||
"very complex type used. Consider factoring parts into `type` definitions");
|
||||
if score > self.threshold {
|
||||
span_lint(cx,
|
||||
TYPE_COMPLEXITY,
|
||||
ty.span,
|
||||
"very complex type used. Consider factoring parts into `type` definitions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Walks a type and assigns a complexity score to it.
|
||||
struct TypeComplexityVisitor {
|
||||
/// total complexity score of the type
|
||||
score: u32,
|
||||
score: u64,
|
||||
/// current nesting level
|
||||
nest: u32,
|
||||
nest: u64,
|
||||
}
|
||||
|
||||
impl<'v> Visitor<'v> for TypeComplexityVisitor {
|
||||
|
|
Loading…
Reference in a new issue