Fix dogfood failures by refactoring open_options

This commit is contained in:
Manish Goregaokar
2016-01-04 10:13:56 +05:30
parent c9342d0121
commit c1a99fdd90
2 changed files with 75 additions and 122 deletions

View File

@@ -1,6 +1,7 @@
#![feature(plugin_registrar, box_syntax)] #![feature(plugin_registrar, box_syntax)]
#![feature(rustc_private, collections)] #![feature(rustc_private, collections)]
#![feature(num_bits_bytes, iter_arith)] #![feature(num_bits_bytes, iter_arith)]
#![feature(custom_attribute)]
#![allow(unknown_lints)] #![allow(unknown_lints)]
// this only exists to allow the "dogfood" integration test to work // this only exists to allow the "dogfood" integration test to work
@@ -77,6 +78,7 @@ mod reexport {
} }
#[plugin_registrar] #[plugin_registrar]
#[rustfmt_skip]
pub fn plugin_registrar(reg: &mut Registry) { pub fn plugin_registrar(reg: &mut Registry) {
reg.register_late_lint_pass(box types::TypePass); reg.register_late_lint_pass(box types::TypePass);
reg.register_late_lint_pass(box misc::TopLevelRefPass); reg.register_late_lint_pass(box misc::TopLevelRefPass);
@@ -130,8 +132,8 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_late_lint_pass(box array_indexing::ArrayIndexing); reg.register_late_lint_pass(box array_indexing::ArrayIndexing);
reg.register_late_lint_pass(box panic::PanicPass); reg.register_late_lint_pass(box panic::PanicPass);
reg.register_lint_group("clippy_pedantic",
vec![ reg.register_lint_group("clippy_pedantic", vec![
methods::OPTION_UNWRAP_USED, methods::OPTION_UNWRAP_USED,
methods::RESULT_UNWRAP_USED, methods::RESULT_UNWRAP_USED,
methods::WRONG_PUB_SELF_CONVENTION, methods::WRONG_PUB_SELF_CONVENTION,
@@ -150,8 +152,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
unicode::UNICODE_NOT_NFC, unicode::UNICODE_NOT_NFC,
]); ]);
reg.register_lint_group("clippy", reg.register_lint_group("clippy", vec![
vec![
approx_const::APPROX_CONSTANT, approx_const::APPROX_CONSTANT,
array_indexing::OUT_OF_BOUNDS_INDEXING, array_indexing::OUT_OF_BOUNDS_INDEXING,
attrs::INLINE_ALWAYS, attrs::INLINE_ALWAYS,

View File

@@ -40,7 +40,7 @@ impl LateLintPass for NonSensicalOpenOptions {
} }
} }
#[derive(Debug)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Argument { enum Argument {
True, True,
False, False,
@@ -104,130 +104,82 @@ fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOp
} }
} }
fn check_for_duplicates(cx: &LateContext, options: &[(OpenOption, Argument)], span: Span) { fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span: Span) {
let (mut create, mut append, mut truncate, mut read, mut write) = (false, false, false, false, false);
let (mut create_arg, mut append_arg, mut truncate_arg, mut read_arg, mut write_arg) = (false,
false,
false,
false,
false);
// This code is almost duplicated (oh, the irony), but I haven't found a way to unify it. // This code is almost duplicated (oh, the irony), but I haven't found a way to unify it.
if options.iter()
.filter(|o| {
if let (OpenOption::Create, _) = **o {
true
} else {
false
}
})
.count() > 1 {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"create\" is called more than once");
}
if options.iter()
.filter(|o| {
if let (OpenOption::Append, _) = **o {
true
} else {
false
}
})
.count() > 1 {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"append\" is called more than once");
}
if options.iter()
.filter(|o| {
if let (OpenOption::Truncate, _) = **o {
true
} else {
false
}
})
.count() > 1 {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"truncate\" is called more than once");
}
if options.iter()
.filter(|o| {
if let (OpenOption::Read, _) = **o {
true
} else {
false
}
})
.count() > 1 {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"read\" is called more than once");
}
if options.iter()
.filter(|o| {
if let (OpenOption::Write, _) = **o {
true
} else {
false
}
})
.count() > 1 {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"write\" is called more than once");
}
}
fn check_for_inconsistencies(cx: &LateContext, options: &[(OpenOption, Argument)], span: Span) { for option in options {
// Truncate + read makes no sense. match *option {
if options.iter() (OpenOption::Create, arg) => {
.filter(|o| { if create {
if let (OpenOption::Read, Argument::True) = **o { span_lint(cx,
true NONSENSICAL_OPEN_OPTIONS,
} else { span,
false "The method \"create\" is called more than once");
} } else {
}) create = true
.count() > 0 && }
options.iter() create_arg = create_arg || (arg == Argument::True);;
.filter(|o| { }
if let (OpenOption::Truncate, Argument::True) = **o { (OpenOption::Append, arg) => {
true if append {
} else { span_lint(cx,
false NONSENSICAL_OPEN_OPTIONS,
} span,
}) "The method \"append\" is called more than once");
.count() > 0 { } else {
append = true
}
append_arg = append_arg || (arg == Argument::True);;
}
(OpenOption::Truncate, arg) => {
if truncate {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"truncate\" is called more than once");
} else {
truncate = true
}
truncate_arg = truncate_arg || (arg == Argument::True);
}
(OpenOption::Read, arg) => {
if read {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"read\" is called more than once");
} else {
read = true
}
read_arg = read_arg || (arg == Argument::True);;
}
(OpenOption::Write, arg) => {
if write {
span_lint(cx,
NONSENSICAL_OPEN_OPTIONS,
span,
"The method \"write\" is called more than once");
} else {
write = true
}
write_arg = write_arg || (arg == Argument::True);;
}
}
}
if read && truncate && read_arg && truncate_arg {
span_lint(cx, NONSENSICAL_OPEN_OPTIONS, span, "File opened with \"truncate\" and \"read\""); span_lint(cx, NONSENSICAL_OPEN_OPTIONS, span, "File opened with \"truncate\" and \"read\"");
} }
if append && truncate && append_arg && truncate_arg {
// Append + truncate makes no sense.
if options.iter()
.filter(|o| {
if let (OpenOption::Append, Argument::True) = **o {
true
} else {
false
}
})
.count() > 0 &&
options.iter()
.filter(|o| {
if let (OpenOption::Truncate, Argument::True) = **o {
true
} else {
false
}
})
.count() > 0 {
span_lint(cx, span_lint(cx,
NONSENSICAL_OPEN_OPTIONS, NONSENSICAL_OPEN_OPTIONS,
span, span,
"File opened with \"append\" and \"truncate\""); "File opened with \"append\" and \"truncate\"");
} }
} }
fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span: Span) {
check_for_duplicates(cx, options, span);
check_for_inconsistencies(cx, options, span);
}