Fix dogfood failures by refactoring open_options
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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| {
|
for option in options {
|
||||||
if let (OpenOption::Create, _) = **o {
|
match *option {
|
||||||
true
|
(OpenOption::Create, arg) => {
|
||||||
} else {
|
if create {
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.count() > 1 {
|
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NONSENSICAL_OPEN_OPTIONS,
|
NONSENSICAL_OPEN_OPTIONS,
|
||||||
span,
|
span,
|
||||||
"The method \"create\" is called more than once");
|
"The method \"create\" is called more than once");
|
||||||
}
|
|
||||||
if options.iter()
|
|
||||||
.filter(|o| {
|
|
||||||
if let (OpenOption::Append, _) = **o {
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
false
|
create = true
|
||||||
}
|
}
|
||||||
})
|
create_arg = create_arg || (arg == Argument::True);;
|
||||||
.count() > 1 {
|
}
|
||||||
|
(OpenOption::Append, arg) => {
|
||||||
|
if append {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NONSENSICAL_OPEN_OPTIONS,
|
NONSENSICAL_OPEN_OPTIONS,
|
||||||
span,
|
span,
|
||||||
"The method \"append\" is called more than once");
|
"The method \"append\" is called more than once");
|
||||||
}
|
|
||||||
if options.iter()
|
|
||||||
.filter(|o| {
|
|
||||||
if let (OpenOption::Truncate, _) = **o {
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
false
|
append = true
|
||||||
}
|
}
|
||||||
})
|
append_arg = append_arg || (arg == Argument::True);;
|
||||||
.count() > 1 {
|
}
|
||||||
|
(OpenOption::Truncate, arg) => {
|
||||||
|
if truncate {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NONSENSICAL_OPEN_OPTIONS,
|
NONSENSICAL_OPEN_OPTIONS,
|
||||||
span,
|
span,
|
||||||
"The method \"truncate\" is called more than once");
|
"The method \"truncate\" is called more than once");
|
||||||
}
|
|
||||||
if options.iter()
|
|
||||||
.filter(|o| {
|
|
||||||
if let (OpenOption::Read, _) = **o {
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
false
|
truncate = true
|
||||||
}
|
}
|
||||||
})
|
truncate_arg = truncate_arg || (arg == Argument::True);
|
||||||
.count() > 1 {
|
}
|
||||||
|
(OpenOption::Read, arg) => {
|
||||||
|
if read {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NONSENSICAL_OPEN_OPTIONS,
|
NONSENSICAL_OPEN_OPTIONS,
|
||||||
span,
|
span,
|
||||||
"The method \"read\" is called more than once");
|
"The method \"read\" is called more than once");
|
||||||
}
|
|
||||||
if options.iter()
|
|
||||||
.filter(|o| {
|
|
||||||
if let (OpenOption::Write, _) = **o {
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
false
|
read = true
|
||||||
}
|
}
|
||||||
})
|
read_arg = read_arg || (arg == Argument::True);;
|
||||||
.count() > 1 {
|
}
|
||||||
|
(OpenOption::Write, arg) => {
|
||||||
|
if write {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NONSENSICAL_OPEN_OPTIONS,
|
NONSENSICAL_OPEN_OPTIONS,
|
||||||
span,
|
span,
|
||||||
"The method \"write\" is called more than once");
|
"The method \"write\" is called more than once");
|
||||||
|
} else {
|
||||||
|
write = true
|
||||||
|
}
|
||||||
|
write_arg = write_arg || (arg == Argument::True);;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn check_for_inconsistencies(cx: &LateContext, options: &[(OpenOption, Argument)], span: Span) {
|
if read && truncate && read_arg && truncate_arg {
|
||||||
// Truncate + read makes no sense.
|
|
||||||
if options.iter()
|
|
||||||
.filter(|o| {
|
|
||||||
if let (OpenOption::Read, 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, 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);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user