-
Notifications
You must be signed in to change notification settings - Fork 895
/
plugins.rs
112 lines (106 loc) · 3.65 KB
/
plugins.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use log::error;
use rustc_hash::FxHashSet;
use rustpython_ast::{Constant, Expr, ExprKind, Stmt, StmtKind};
use crate::ast::types::Range;
use crate::autofix::helpers::delete_stmt;
use crate::autofix::Fix;
use crate::checkers::ast::Checker;
use crate::registry::{Check, CheckCode, CheckKind};
/// PIE790
pub fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) {
if body.len() > 1 {
// This only catches the case in which a docstring makes a `pass` statement
// redundant. Consider removing all `pass` statements instead.
let docstring_stmt = &body[0];
let pass_stmt = &body[1];
let StmtKind::Expr { value } = &docstring_stmt.node else {
return;
};
if matches!(
value.node,
ExprKind::Constant {
value: Constant::Str(..),
..
}
) {
if matches!(pass_stmt.node, StmtKind::Pass) {
let mut check =
Check::new(CheckKind::NoUnnecessaryPass, Range::from_located(pass_stmt));
if checker.patch(&CheckCode::PIE790) {
match delete_stmt(pass_stmt, None, &[], checker.locator) {
Ok(fix) => {
check.amend(fix);
}
Err(e) => {
error!("Failed to delete `pass` statement: {}", e);
}
}
}
checker.add_check(check);
}
}
}
}
/// PIE794
pub fn dupe_class_field_definitions(checker: &mut Checker, bases: &[Expr], body: &[Stmt]) {
if bases.is_empty() {
return;
}
let mut seen_targets = FxHashSet::default();
for stmt in body {
// Extract the property name from the assignment statement.
let target = match &stmt.node {
StmtKind::Assign { targets, .. } => {
if targets.len() != 1 {
continue;
}
if let ExprKind::Name { id, .. } = &targets[0].node {
id
} else {
continue;
}
}
StmtKind::AnnAssign { target, .. } => {
if let ExprKind::Name { id, .. } = &target.node {
id
} else {
continue;
}
}
_ => continue,
};
if seen_targets.contains(target) {
let mut check = Check::new(
CheckKind::DupeClassFieldDefinitions(target.to_string()),
Range::from_located(stmt),
);
if checker.patch(&CheckCode::PIE794) {
check.amend(Fix::deletion(stmt.location, stmt.end_location.unwrap()));
}
checker.add_check(check);
} else {
seen_targets.insert(target);
}
}
}
/// PIE807
pub fn prefer_list_builtin(checker: &mut Checker, expr: &Expr) {
let ExprKind::Lambda { args, body } = &expr.node else {
unreachable!("Expected ExprKind::Lambda");
};
if args.args.is_empty() {
if let ExprKind::List { elts, .. } = &body.node {
if elts.is_empty() {
let mut check = Check::new(CheckKind::PreferListBuiltin, Range::from_located(expr));
if checker.patch(&CheckCode::PIE807) {
check.amend(Fix::replacement(
"list".to_string(),
expr.location,
expr.end_location.unwrap(),
));
}
checker.add_check(check);
}
}
}
}