Add new lint on function naming check (the '_')

This commit is contained in:
Guillaume Gomez 2016-01-03 14:00:42 +01:00
parent 4b9912c2b0
commit abfb1d3ca1
5 changed files with 52 additions and 5 deletions

View file

@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your Rust code.
[Jump to usage instructions](#usage) [Jump to usage instructions](#usage)
##Lints ##Lints
There are 88 lints included in this crate: There are 89 lints included in this crate:
name | default | meaning name | default | meaning
---------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -24,6 +24,7 @@ name
[cmp_owned](https://github.com/Manishearth/rust-clippy/wiki#cmp_owned) | warn | creating owned instances for comparing with others, e.g. `x == "foo".to_string()` [cmp_owned](https://github.com/Manishearth/rust-clippy/wiki#cmp_owned) | warn | creating owned instances for comparing with others, e.g. `x == "foo".to_string()`
[collapsible_if](https://github.com/Manishearth/rust-clippy/wiki#collapsible_if) | warn | two nested `if`-expressions can be collapsed into one, e.g. `if x { if y { foo() } }` can be written as `if x && y { foo() }` [collapsible_if](https://github.com/Manishearth/rust-clippy/wiki#collapsible_if) | warn | two nested `if`-expressions can be collapsed into one, e.g. `if x { if y { foo() } }` can be written as `if x && y { foo() }`
[cyclomatic_complexity](https://github.com/Manishearth/rust-clippy/wiki#cyclomatic_complexity) | warn | finds functions that should be split up into multiple functions [cyclomatic_complexity](https://github.com/Manishearth/rust-clippy/wiki#cyclomatic_complexity) | warn | finds functions that should be split up into multiple functions
[duplicate_underscore_argument](https://github.com/Manishearth/rust-clippy/wiki#duplicate_underscore_argument)| warn | Function arguments having names which only differ by an underscore
[empty_loop](https://github.com/Manishearth/rust-clippy/wiki#empty_loop) | warn | empty `loop {}` detected [empty_loop](https://github.com/Manishearth/rust-clippy/wiki#empty_loop) | warn | empty `loop {}` detected
[eq_op](https://github.com/Manishearth/rust-clippy/wiki#eq_op) | warn | equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`) [eq_op](https://github.com/Manishearth/rust-clippy/wiki#eq_op) | warn | equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)
[explicit_counter_loop](https://github.com/Manishearth/rust-clippy/wiki#explicit_counter_loop) | warn | for-looping with an explicit counter when `_.enumerate()` would do [explicit_counter_loop](https://github.com/Manishearth/rust-clippy/wiki#explicit_counter_loop) | warn | for-looping with an explicit counter when `_.enumerate()` would do

View file

@ -193,6 +193,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
misc::REDUNDANT_PATTERN, misc::REDUNDANT_PATTERN,
misc::TOPLEVEL_REF_ARG, misc::TOPLEVEL_REF_ARG,
misc::USED_UNDERSCORE_BINDING, misc::USED_UNDERSCORE_BINDING,
misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
misc_early::UNNEEDED_FIELD_PATTERN, misc_early::UNNEEDED_FIELD_PATTERN,
mut_reference::UNNECESSARY_MUT_PASSED, mut_reference::UNNECESSARY_MUT_PASSED,
mutex_atomic::MUTEX_ATOMIC, mutex_atomic::MUTEX_ATOMIC,

View file

@ -1,8 +1,11 @@
//use rustc_front::hir::*;
use rustc::lint::*; use rustc::lint::*;
use std::collections::HashMap;
use syntax::ast::*; use syntax::ast::*;
use syntax::codemap::Span;
use syntax::print::pprust;
use syntax::visit::FnKind;
use utils::{span_lint, span_help_and_lint}; use utils::{span_lint, span_help_and_lint};
@ -16,12 +19,22 @@ use utils::{span_lint, span_help_and_lint};
declare_lint!(pub UNNEEDED_FIELD_PATTERN, Warn, declare_lint!(pub UNNEEDED_FIELD_PATTERN, Warn,
"Struct fields are bound to a wildcard instead of using `..`"); "Struct fields are bound to a wildcard instead of using `..`");
/// **What it does:** This lint `Warn`s on function arguments having the same name except one starts with '_'
///
/// **Why is this bad?** It makes source code documentation more difficult
///
/// **Known problems:** None.
///
/// **Example:** `fn foo(a: i32, _a: i32) {}`
declare_lint!(pub DUPLICATE_UNDERSCORE_ARGUMENT, Warn,
"Function arguments having names which only differ by an underscore");
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct MiscEarly; pub struct MiscEarly;
impl LintPass for MiscEarly { impl LintPass for MiscEarly {
fn get_lints(&self) -> LintArray { fn get_lints(&self) -> LintArray {
lint_array!(UNNEEDED_FIELD_PATTERN) lint_array!(UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT)
} }
} }
@ -77,4 +90,23 @@ impl EarlyLintPass for MiscEarly {
} }
} }
} }
fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
let mut registered_names : HashMap<String, Span> = HashMap::new();
for ref arg in &decl.inputs {
let arg_name = pprust::pat_to_string(&arg.pat);
if arg_name.starts_with("_") {
if let Some(correspondance) = registered_names.get(&arg_name[1..].to_owned()) {
span_lint(cx, DUPLICATE_UNDERSCORE_ARGUMENT, *correspondance,
&format!("`{}` already exists, having another argument having almost \
the same name makes code comprehension and documentation \
more difficult", arg_name[1..].to_owned()));
}
} else {
registered_names.insert(arg_name.to_owned(), arg.pat.span.clone());
}
}
}
} }

View file

@ -0,0 +1,13 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(duplicate_underscore_argument)]
#[allow(dead_code, unused)]
fn join_the_dark_side(darth: i32, _darth: i32) {} //~ERROR `darth` already exists
fn join_the_light_side(knight: i32, _master: i32) {} // the Force is strong with this one
fn main() {
join_the_dark_side(0, 0);
join_the_light_side(0, 0);
}

View file

@ -23,4 +23,4 @@ fn main() {
Foo { b: 0, .. } => {} // should be OK Foo { b: 0, .. } => {} // should be OK
Foo { .. } => {} // and the Force might be with this one Foo { .. } => {} // and the Force might be with this one
} }
} }