Avoid nested-if violations when outer-if has else clause (#2095)

It looks like we need `do`-`while`-like semantics here with an additional outer check.

Closes #2094.
This commit is contained in:
Charlie Marsh 2023-01-22 17:40:56 -05:00 committed by GitHub
parent 4fb0c6e3ad
commit 8d46d3bfa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 5 deletions

View File

@ -92,3 +92,40 @@ if node.module:
"multiprocessing."
):
print("Bad module!")
# OK
if a:
if b:
print("foo")
else:
print("bar")
# OK
if a:
if b:
if c:
print("foo")
else:
print("bar")
else:
print("bar")
# OK
if a:
# SIM 102
if b:
if c:
print("foo")
else:
print("bar")
# OK
if a:
if b:
if c:
print("foo")
print("baz")
else:
print("bar")

View File

@ -1386,6 +1386,7 @@ where
stmt,
test,
body,
orelse,
self.current_stmt_parent().map(Into::into),
);
}

View File

@ -50,7 +50,7 @@ fn is_main_check(expr: &Expr) -> bool {
/// ```
fn find_last_nested_if(body: &[Stmt]) -> Option<(&Expr, &Stmt)> {
let [Stmt { node: StmtKind::If { test, body: inner_body, orelse }, ..}] = body else { return None };
if !(orelse.is_empty() && body.len() == 1) {
if !orelse.is_empty() {
return None;
}
find_last_nested_if(inner_body).or_else(|| {
@ -67,12 +67,10 @@ pub fn nested_if_statements(
stmt: &Stmt,
test: &Expr,
body: &[Stmt],
orelse: &[Stmt],
parent: Option<&Stmt>,
) {
if is_main_check(test) {
return;
}
// If the parent could contain a nested if-statement, abort.
if let Some(parent) = parent {
if let StmtKind::If { body, orelse, .. } = &parent.node {
if orelse.is_empty() && body.len() == 1 {
@ -81,6 +79,16 @@ pub fn nested_if_statements(
}
}
// If this if-statement has an else clause, or more than one child, abort.
if !(orelse.is_empty() && body.len() == 1) {
return;
}
if is_main_check(test) {
return;
}
// Find the deepest nested if-statement, to inform the range.
let Some((test, first_stmt)) = find_last_nested_if(body) else {
return;
};

View File

@ -148,4 +148,21 @@ expression: diagnostics
row: 95
column: 0
parent: ~
- kind:
NestedIfStatements: ~
location:
row: 117
column: 4
end_location:
row: 118
column: 13
fix:
content: " if b and c:\n print(\"foo\")\n"
location:
row: 117
column: 0
end_location:
row: 120
column: 0
parent: ~