mirror of https://github.com/astral-sh/ruff
Add a ::new
This commit is contained in:
parent
1eafc5a902
commit
7e35c18946
|
|
@ -6,6 +6,8 @@ use rustpython_parser::ast::Location;
|
||||||
|
|
||||||
use crate::checks::Check;
|
use crate::checks::Check;
|
||||||
|
|
||||||
|
// TODO(charlie): This should take Vec<Fix>.
|
||||||
|
// TODO(charlie): Add tests.
|
||||||
pub fn apply_fixes(checks: &mut Vec<Check>, contents: &str, path: &Path) -> Result<()> {
|
pub fn apply_fixes(checks: &mut Vec<Check>, contents: &str, path: &Path) -> Result<()> {
|
||||||
if checks.iter().all(|check| check.fix.is_none()) {
|
if checks.iter().all(|check| check.fix.is_none()) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
|
||||||
180
src/check_ast.rs
180
src/check_ast.rs
|
|
@ -106,12 +106,10 @@ impl Visitor for Checker<'_> {
|
||||||
if let Some(scope) = self.scopes.last() {
|
if let Some(scope) = self.scopes.last() {
|
||||||
match scope.kind {
|
match scope.kind {
|
||||||
ScopeKind::Class | ScopeKind::Module => {
|
ScopeKind::Class | ScopeKind::Module => {
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::ReturnOutsideFunction,
|
CheckKind::ReturnOutsideFunction,
|
||||||
location: stmt.location,
|
stmt.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -136,20 +134,22 @@ impl Visitor for Checker<'_> {
|
||||||
kind: BindingKind::Builtin,
|
kind: BindingKind::Builtin,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
self.checks.push(Check {
|
let mut check = Check::new(
|
||||||
kind: CheckKind::UselessObjectInheritance(
|
CheckKind::UselessObjectInheritance(name.to_string()),
|
||||||
name.to_string(),
|
expr.location,
|
||||||
),
|
);
|
||||||
location: expr.location,
|
// TODO(charlie): Only bother to do this if autofix is
|
||||||
fix: fixer::remove_object_base(
|
// enabled.
|
||||||
self.lines,
|
if let Some(fix) = fixer::remove_object_base(
|
||||||
&stmt.location,
|
self.lines,
|
||||||
expr.location,
|
&stmt.location,
|
||||||
bases,
|
expr.location,
|
||||||
keywords,
|
bases,
|
||||||
),
|
keywords,
|
||||||
fixed: false,
|
) {
|
||||||
});
|
check.amend(fix);
|
||||||
|
}
|
||||||
|
self.checks.push(check);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -263,12 +263,8 @@ impl Visitor for Checker<'_> {
|
||||||
.select
|
.select
|
||||||
.contains(CheckKind::ImportStarUsage.code())
|
.contains(CheckKind::ImportStarUsage.code())
|
||||||
{
|
{
|
||||||
self.checks.push(Check {
|
self.checks
|
||||||
kind: CheckKind::ImportStarUsage,
|
.push(Check::new(CheckKind::ImportStarUsage, stmt.location));
|
||||||
location: stmt.location,
|
|
||||||
fix: None,
|
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let binding = Binding {
|
let binding = Binding {
|
||||||
|
|
@ -287,12 +283,8 @@ impl Visitor for Checker<'_> {
|
||||||
if self.settings.select.contains(CheckKind::IfTuple.code()) {
|
if self.settings.select.contains(CheckKind::IfTuple.code()) {
|
||||||
if let ExprKind::Tuple { elts, .. } = &test.node {
|
if let ExprKind::Tuple { elts, .. } = &test.node {
|
||||||
if !elts.is_empty() {
|
if !elts.is_empty() {
|
||||||
self.checks.push(Check {
|
self.checks
|
||||||
kind: CheckKind::IfTuple,
|
.push(Check::new(CheckKind::IfTuple, stmt.location));
|
||||||
location: stmt.location,
|
|
||||||
fix: None,
|
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -308,23 +300,19 @@ impl Visitor for Checker<'_> {
|
||||||
ExprKind::Call { func, .. } => {
|
ExprKind::Call { func, .. } => {
|
||||||
if let ExprKind::Name { id, .. } = &func.node {
|
if let ExprKind::Name { id, .. } = &func.node {
|
||||||
if id == "NotImplemented" {
|
if id == "NotImplemented" {
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::RaiseNotImplemented,
|
CheckKind::RaiseNotImplemented,
|
||||||
location: stmt.location,
|
stmt.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
if id == "NotImplemented" {
|
if id == "NotImplemented" {
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::RaiseNotImplemented,
|
CheckKind::RaiseNotImplemented,
|
||||||
location: stmt.location,
|
stmt.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -341,12 +329,8 @@ impl Visitor for Checker<'_> {
|
||||||
if self.settings.select.contains(CheckKind::AssertTuple.code()) {
|
if self.settings.select.contains(CheckKind::AssertTuple.code()) {
|
||||||
if let ExprKind::Tuple { elts, .. } = &test.node {
|
if let ExprKind::Tuple { elts, .. } = &test.node {
|
||||||
if !elts.is_empty() {
|
if !elts.is_empty() {
|
||||||
self.checks.push(Check {
|
self.checks
|
||||||
kind: CheckKind::AssertTuple,
|
.push(Check::new(CheckKind::AssertTuple, stmt.location));
|
||||||
location: stmt.location,
|
|
||||||
fix: None,
|
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -407,12 +391,10 @@ impl Visitor for Checker<'_> {
|
||||||
&& name != "__traceback_supplement__"
|
&& name != "__traceback_supplement__"
|
||||||
&& matches!(binding.kind, BindingKind::Assignment)
|
&& matches!(binding.kind, BindingKind::Assignment)
|
||||||
{
|
{
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::UnusedVariable(name.to_string()),
|
CheckKind::UnusedVariable(name.to_string()),
|
||||||
location: binding.location,
|
binding.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,12 +445,8 @@ impl Visitor for Checker<'_> {
|
||||||
&& matches!(scope.kind, ScopeKind::Class)
|
&& matches!(scope.kind, ScopeKind::Class)
|
||||||
|| matches!(scope.kind, ScopeKind::Module)
|
|| matches!(scope.kind, ScopeKind::Module)
|
||||||
{
|
{
|
||||||
self.checks.push(Check {
|
self.checks
|
||||||
kind: CheckKind::YieldOutsideFunction,
|
.push(Check::new(CheckKind::YieldOutsideFunction, expr.location));
|
||||||
location: expr.location,
|
|
||||||
fix: None,
|
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::JoinedStr { values } => {
|
ExprKind::JoinedStr { values } => {
|
||||||
|
|
@ -481,12 +459,10 @@ impl Visitor for Checker<'_> {
|
||||||
.iter()
|
.iter()
|
||||||
.any(|value| matches!(value.node, ExprKind::FormattedValue { .. }))
|
.any(|value| matches!(value.node, ExprKind::FormattedValue { .. }))
|
||||||
{
|
{
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::FStringMissingPlaceholders,
|
CheckKind::FStringMissingPlaceholders,
|
||||||
location: expr.location,
|
expr.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
self.in_f_string = true;
|
self.in_f_string = true;
|
||||||
}
|
}
|
||||||
|
|
@ -553,12 +529,10 @@ impl Visitor for Checker<'_> {
|
||||||
if let Some(binding) = scope.values.remove(name) {
|
if let Some(binding) = scope.values.remove(name) {
|
||||||
if self.settings.select.contains(&CheckCode::F841) && binding.used.is_none()
|
if self.settings.select.contains(&CheckCode::F841) && binding.used.is_none()
|
||||||
{
|
{
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::UnusedVariable(name.to_string()),
|
CheckKind::UnusedVariable(name.to_string()),
|
||||||
location: excepthandler.location,
|
excepthandler.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -596,12 +570,8 @@ impl Visitor for Checker<'_> {
|
||||||
for arg in all_arguments {
|
for arg in all_arguments {
|
||||||
let ident = &arg.node.arg;
|
let ident = &arg.node.arg;
|
||||||
if idents.contains(ident.as_str()) {
|
if idents.contains(ident.as_str()) {
|
||||||
self.checks.push(Check {
|
self.checks
|
||||||
kind: CheckKind::DuplicateArgumentName,
|
.push(Check::new(CheckKind::DuplicateArgumentName, arg.location));
|
||||||
location: arg.location,
|
|
||||||
fix: None,
|
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
idents.insert(ident);
|
idents.insert(ident);
|
||||||
|
|
@ -695,12 +665,10 @@ impl Checker<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.settings.select.contains(&CheckCode::F821) {
|
if self.settings.select.contains(&CheckCode::F821) {
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::UndefinedName(id.clone()),
|
CheckKind::UndefinedName(id.clone()),
|
||||||
location: expr.location,
|
expr.location,
|
||||||
fix: None,
|
))
|
||||||
fixed: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -724,12 +692,10 @@ impl Checker<'_> {
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if let Some(scope_id) = used {
|
if let Some(scope_id) = used {
|
||||||
if scope_id == current.id {
|
if scope_id == current.id {
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::UndefinedLocal(id.clone()),
|
CheckKind::UndefinedLocal(id.clone()),
|
||||||
location: expr.location,
|
expr.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -776,12 +742,10 @@ impl Checker<'_> {
|
||||||
if current.values.remove(id).is_none()
|
if current.values.remove(id).is_none()
|
||||||
&& self.settings.select.contains(&CheckCode::F821)
|
&& self.settings.select.contains(&CheckCode::F821)
|
||||||
{
|
{
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::UndefinedName(id.clone()),
|
CheckKind::UndefinedName(id.clone()),
|
||||||
location: expr.location,
|
expr.location,
|
||||||
fix: None,
|
))
|
||||||
fixed: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -815,12 +779,10 @@ impl Checker<'_> {
|
||||||
if let Some(names) = all_names {
|
if let Some(names) = all_names {
|
||||||
for name in names {
|
for name in names {
|
||||||
if !scope.values.contains_key(name) {
|
if !scope.values.contains_key(name) {
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::UndefinedExport(name.to_string()),
|
CheckKind::UndefinedExport(name.to_string()),
|
||||||
location: binding.location,
|
binding.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -838,12 +800,10 @@ impl Checker<'_> {
|
||||||
match &binding.kind {
|
match &binding.kind {
|
||||||
BindingKind::Importation(full_name)
|
BindingKind::Importation(full_name)
|
||||||
| BindingKind::SubmoduleImportation(full_name) => {
|
| BindingKind::SubmoduleImportation(full_name) => {
|
||||||
self.checks.push(Check {
|
self.checks.push(Check::new(
|
||||||
kind: CheckKind::UnusedImport(full_name.to_string()),
|
CheckKind::UnusedImport(full_name.to_string()),
|
||||||
location: binding.location,
|
binding.location,
|
||||||
fix: None,
|
));
|
||||||
fixed: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,10 @@ pub fn check_lines(checks: &mut Vec<Check>, contents: &str, settings: &Settings)
|
||||||
|
|
||||||
// Enforce line length.
|
// Enforce line length.
|
||||||
if enforce_line_too_long && should_enforce_line_length(line, settings.line_length) {
|
if enforce_line_too_long && should_enforce_line_length(line, settings.line_length) {
|
||||||
let check = Check {
|
let check = Check::new(
|
||||||
kind: CheckKind::LineTooLong,
|
CheckKind::LineTooLong,
|
||||||
location: Location::new(row + 1, settings.line_length + 1),
|
Location::new(row + 1, settings.line_length + 1),
|
||||||
fix: None,
|
);
|
||||||
fixed: false,
|
|
||||||
};
|
|
||||||
if !check.is_inline_ignored(line) {
|
if !check.is_inline_ignored(line) {
|
||||||
line_checks.push(check);
|
line_checks.push(check);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,19 @@ static NO_QA_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||||
static SPLIT_COMMA_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"[,\s]").expect("Invalid regex"));
|
static SPLIT_COMMA_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"[,\s]").expect("Invalid regex"));
|
||||||
|
|
||||||
impl Check {
|
impl Check {
|
||||||
|
pub fn new(kind: CheckKind, location: Location) -> Self {
|
||||||
|
Self {
|
||||||
|
kind,
|
||||||
|
location,
|
||||||
|
fix: None,
|
||||||
|
fixed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn amend(&mut self, fix: Fix) {
|
||||||
|
self.fix = Some(fix);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_inline_ignored(&self, line: &str) -> bool {
|
pub fn is_inline_ignored(&self, line: &str) -> bool {
|
||||||
match NO_QA_REGEX.captures(line) {
|
match NO_QA_REGEX.captures(line) {
|
||||||
Some(caps) => match caps.name("codes") {
|
Some(caps) => match caps.name("codes") {
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,8 @@ fn run_once(
|
||||||
fn report_once(messages: &[Message]) -> Result<()> {
|
fn report_once(messages: &[Message]) -> Result<()> {
|
||||||
let (fixed, outstanding): (Vec<&Message>, Vec<&Message>) =
|
let (fixed, outstanding): (Vec<&Message>, Vec<&Message>) =
|
||||||
messages.iter().partition(|message| message.fixed);
|
messages.iter().partition(|message| message.fixed);
|
||||||
|
|
||||||
|
// TODO(charlie): If autofix is disabled, but some rules are fixable, tell the user.
|
||||||
if fixed.is_empty() {
|
if fixed.is_empty() {
|
||||||
println!("Found {} error(s).", messages.len());
|
println!("Found {} error(s).", messages.len());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue