Skip to content

Commit

Permalink
Separate method
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jan 22, 2024
1 parent 1e42501 commit 34c274d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 37 deletions.
52 changes: 29 additions & 23 deletions crates/ruff_linter/src/rules/pylint/rules/collapsible_else_if.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use ast::whitespace::indentation;
use ruff_python_ast::{self as ast, ElifElseClause, Stmt};
use ruff_text_size::{Ranged, TextRange};

use anyhow::Result;
use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation};

use ast::whitespace::indentation;
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, ElifElseClause, Stmt};
use ruff_python_codegen::Stylist;
use ruff_source_file::Locator;
use ruff_text_size::{Ranged, TextRange};

use crate::checkers::ast::Checker;
use crate::rules::pyupgrade::fixes::adjust_indentation;
Expand Down Expand Up @@ -48,13 +48,14 @@ pub struct CollapsibleElseIf;

impl Violation for CollapsibleElseIf {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;

#[derive_message_formats]
fn message(&self) -> String {
format!("Use `elif` instead of `else` then `if`, to reduce indentation")
}

fn fix_title(&self) -> Option<String> {
Some("Use `elif` instead of `else` then `if`, to reduce indentation".to_string())
Some("Convert to `elif`".to_string())
}
}

Expand Down Expand Up @@ -85,13 +86,16 @@ pub(crate) fn collapsible_else_if(checker: &mut Checker, stmt: &Stmt) {
);

if checker.settings.preview.is_enabled() {
diagnostic.try_set_fix(|| do_fix(first, else_clause, checker.locator(), checker.stylist()));
diagnostic.try_set_fix(|| {
convert_to_elif(first, else_clause, checker.locator(), checker.stylist())
});
}

checker.diagnostics.push(diagnostic);
}

fn do_fix(
/// Generate [`Fix`] to convert an `else` block to an `elif` block.
fn convert_to_elif(
first: &Stmt,
else_clause: &ElifElseClause,
locator: &Locator,
Expand All @@ -101,25 +105,27 @@ fn do_fix(
let inner_if_line_end = locator.line_end(first.end());

// Identify the indentation of the loop itself (e.g., the `while` or `for`).
let desired_indentation = indentation(locator, else_clause).unwrap_or("");
let Some(indentation) = indentation(locator, else_clause) else {
return Err(anyhow::anyhow!("`else` is expected to be on its own line"));
};

// Dedent the content from the end of the `else` to the end of the `if`.
let indented = adjust_indentation(
TextRange::new(inner_if_line_start, inner_if_line_end),
desired_indentation,
indentation,
locator,
stylist,
)
.unwrap();

// Unindent the first line (which is the `if` and add `el` to the start)
let fixed_indented = format!("el{}", indented.strip_prefix(desired_indentation).unwrap());

Ok(Fix::applicable_edit(
Edit::range_replacement(
fixed_indented,
TextRange::new(else_clause.start(), inner_if_line_end),
),
Applicability::Safe,
))
)?;

// Strip the indent from the first line of the `if` statement, and add `el` to the start.
let Some(unindented) = indented.strip_prefix(indentation) else {
return Err(anyhow::anyhow!("indented block to start with indentation"));
};
let indented = format!("{indentation}el{unindented}");

Ok(Fix::safe_edit(Edit::replacement(
indented,
locator.line_start(else_clause.start()),
inner_if_line_end,
)))
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ collapsible_else_if.py:37:5: PLR5501 Use `elif` instead of `else` then `if`, to
| |________^ PLR5501
39 | pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

collapsible_else_if.py:45:5: PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
|
Expand All @@ -24,7 +24,7 @@ collapsible_else_if.py:45:5: PLR5501 Use `elif` instead of `else` then `if`, to
47 | pass
48 | else:
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

collapsible_else_if.py:55:5: PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
|
Expand All @@ -38,7 +38,7 @@ collapsible_else_if.py:55:5: PLR5501 Use `elif` instead of `else` then `if`, to
58 | pass
59 | else:
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

collapsible_else_if.py:69:5: PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
|
Expand All @@ -51,7 +51,7 @@ collapsible_else_if.py:69:5: PLR5501 Use `elif` instead of `else` then `if`, to
71 | print(3)
72 | else:
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

collapsible_else_if.py:79:5: PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
|
Expand All @@ -63,7 +63,7 @@ collapsible_else_if.py:79:5: PLR5501 Use `elif` instead of `else` then `if`, to
| |________^ PLR5501
81 | else: pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

collapsible_else_if.py:87:5: PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
|
Expand All @@ -76,7 +76,7 @@ collapsible_else_if.py:87:5: PLR5501 Use `elif` instead of `else` then `if`, to
89 | else:
90 | pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

collapsible_else_if.py:96:5: PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
|
Expand All @@ -89,6 +89,6 @@ collapsible_else_if.py:96:5: PLR5501 Use `elif` instead of `else` then `if`, to
98 | pass
99 | else: pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`


Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ collapsible_else_if.py:37:5: PLR5501 [*] Use `elif` instead of `else` then `if`,
| |________^ PLR5501
39 | pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

Safe fix
34 34 | def not_ok0():
Expand All @@ -37,7 +37,7 @@ collapsible_else_if.py:45:5: PLR5501 [*] Use `elif` instead of `else` then `if`,
47 | pass
48 | else:
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

Safe fix
42 42 | def not_ok1():
Expand Down Expand Up @@ -67,7 +67,7 @@ collapsible_else_if.py:55:5: PLR5501 [*] Use `elif` instead of `else` then `if`,
58 | pass
59 | else:
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

Safe fix
52 52 | def not_ok1_with_comments():
Expand Down Expand Up @@ -97,7 +97,7 @@ collapsible_else_if.py:69:5: PLR5501 [*] Use `elif` instead of `else` then `if`,
71 | print(3)
72 | else:
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

Safe fix
66 66 | print(1)
Expand Down Expand Up @@ -125,7 +125,7 @@ collapsible_else_if.py:79:5: PLR5501 [*] Use `elif` instead of `else` then `if`,
| |________^ PLR5501
81 | else: pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

Safe fix
76 76 | def not_ok3():
Expand All @@ -151,7 +151,7 @@ collapsible_else_if.py:87:5: PLR5501 [*] Use `elif` instead of `else` then `if`,
89 | else:
90 | pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

Safe fix
84 84 | def not_ok4():
Expand All @@ -178,7 +178,7 @@ collapsible_else_if.py:96:5: PLR5501 [*] Use `elif` instead of `else` then `if`,
98 | pass
99 | else: pass
|
= help: Use `elif` instead of `else` then `if`, to reduce indentation
= help: Convert to `elif`

Safe fix
93 93 | def not_ok5():
Expand Down

0 comments on commit 34c274d

Please sign in to comment.