-
Notifications
You must be signed in to change notification settings - Fork 974
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eb884c8
commit c67ba2a
Showing
8 changed files
with
180 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
z = x if x else y # FURB110 | ||
|
||
z = x \ | ||
if x else y # FURB110 | ||
|
||
z = x if x \ | ||
else \ | ||
y # FURB110 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; | ||
use ruff_macros::{derive_message_formats, violation}; | ||
use ruff_python_ast::{self as ast}; | ||
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; | ||
use ruff_text_size::Ranged; | ||
|
||
use crate::checkers::ast::Checker; | ||
use crate::fix::snippet::SourceCodeSnippet; | ||
|
||
/// ## What it does | ||
/// Checks for ternary `if` expressions that can be replaced with | ||
/// `or` expressions. | ||
/// | ||
/// ## Why is this bad? | ||
/// Ternary if statements are more verbose than `or` expressions, and | ||
/// generally have the same functionality. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// z = x if x else y | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// z = x or y | ||
/// ``` | ||
/// | ||
/// Note: if `x` depends on side-effects, then this check should be ignored. | ||
#[violation] | ||
pub struct OrOper { | ||
if_true: SourceCodeSnippet, | ||
if_false: SourceCodeSnippet, | ||
} | ||
|
||
impl Violation for OrOper { | ||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; | ||
|
||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
let OrOper { if_true, if_false } = self; | ||
|
||
match (if_true.full_display(), if_false.full_display()) { | ||
(_, None) | (None, _) => { | ||
format!("Replace ternary `if` expression with `or` expression") | ||
} | ||
(Some(if_true), Some(if_false)) => { | ||
format!( | ||
"Replace `{if_true} if {if_true} or {if_false}` with `{if_true} or {if_false}`" | ||
) | ||
} | ||
} | ||
} | ||
|
||
fn fix_title(&self) -> Option<String> { | ||
Some(format!("Use `or` expression")) | ||
} | ||
} | ||
|
||
/// FURB110 | ||
pub(crate) fn or_oper(checker: &mut Checker, if_expr: &ast::ExprIf) { | ||
let ast::ExprIf { | ||
test, | ||
body, | ||
orelse, | ||
range, | ||
} = if_expr; | ||
|
||
let if_true = body.as_ref(); | ||
let if_true_code = checker.locator().slice(if_true); | ||
let test_expr_code = checker.locator().slice(test.as_ref()); | ||
|
||
if test_expr_code != if_true_code { | ||
return; | ||
} | ||
|
||
let if_false = orelse.as_ref(); | ||
|
||
let mut diagnostic = Diagnostic::new( | ||
OrOper { | ||
if_true: SourceCodeSnippet::from_str(if_true_code), | ||
if_false: SourceCodeSnippet::from_str(checker.locator().slice(if_false)), | ||
}, | ||
*range, | ||
); | ||
|
||
let mut tokenizer = SimpleTokenizer::starts_at(if_true.end(), checker.locator().contents()); | ||
|
||
// find the `else` token to replace with `or` | ||
let else_token = tokenizer | ||
.find(|tok| tok.kind() == SimpleTokenKind::Else) | ||
.expect("else token to exist"); | ||
|
||
let fix = Fix::unsafe_edits( | ||
Edit::range_replacement("or".to_string(), else_token.range()), | ||
[Edit::deletion(if_true.start(), test.start())], | ||
); | ||
|
||
diagnostic.set_fix(fix); | ||
|
||
checker.diagnostics.push(diagnostic); | ||
} |
63 changes: 63 additions & 0 deletions
63
...ter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB110_FURB110.py.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
--- | ||
source: crates/ruff_linter/src/rules/refurb/mod.rs | ||
--- | ||
FURB110.py:1:5: FURB110 [*] Replace `x if x or y` with `x or y` | ||
| | ||
1 | z = x if x else y # FURB110 | ||
| ^^^^^^^^^^^^^ FURB110 | ||
2 | | ||
3 | z = x \ | ||
| | ||
= help: Use `or` expression | ||
|
||
ℹ Unsafe fix | ||
1 |-z = x if x else y # FURB110 | ||
1 |+z = x or y # FURB110 | ||
2 2 | | ||
3 3 | z = x \ | ||
4 4 | if x else y # FURB110 | ||
|
||
FURB110.py:3:5: FURB110 [*] Replace `x if x or y` with `x or y` | ||
| | ||
1 | z = x if x else y # FURB110 | ||
2 | | ||
3 | z = x \ | ||
| _____^ | ||
4 | | if x else y # FURB110 | ||
| |_______________^ FURB110 | ||
5 | | ||
6 | z = x if x \ | ||
| | ||
= help: Use `or` expression | ||
|
||
ℹ Unsafe fix | ||
1 1 | z = x if x else y # FURB110 | ||
2 2 | | ||
3 |-z = x \ | ||
4 |- if x else y # FURB110 | ||
3 |+z = x or y # FURB110 | ||
5 4 | | ||
6 5 | z = x if x \ | ||
7 6 | else \ | ||
|
||
FURB110.py:6:5: FURB110 [*] Replace `x if x or y` with `x or y` | ||
| | ||
4 | if x else y # FURB110 | ||
5 | | ||
6 | z = x if x \ | ||
| _____^ | ||
7 | | else \ | ||
8 | | y # FURB110 | ||
| |_________^ FURB110 | ||
| | ||
= help: Use `or` expression | ||
|
||
ℹ Unsafe fix | ||
3 3 | z = x \ | ||
4 4 | if x else y # FURB110 | ||
5 5 | | ||
6 |-z = x if x \ | ||
7 |- else \ | ||
6 |+z = x \ | ||
7 |+ or \ | ||
8 8 | y # FURB110 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.