diff --git a/ruff_dev/src/round_trip.rs b/ruff_dev/src/round_trip.rs index c528e77b5c..3faa5d6c27 100644 --- a/ruff_dev/src/round_trip.rs +++ b/ruff_dev/src/round_trip.rs @@ -5,9 +5,7 @@ use std::path::PathBuf; use anyhow::Result; use clap::Args; -use ruff::source_code_generator::SourceCodeGenerator; -use ruff::source_code_locator::SourceCodeLocator; -use ruff::source_code_style::SourceCodeStyleDetector; +use ruff::source_code::{Generator, Locator, Stylist}; use rustpython_parser::parser; #[derive(Args)] @@ -20,9 +18,9 @@ pub struct Cli { pub fn main(cli: &Cli) -> Result<()> { let contents = fs::read_to_string(&cli.file)?; let python_ast = parser::parse_program(&contents, &cli.file.to_string_lossy())?; - let locator = SourceCodeLocator::new(&contents); - let stylist = SourceCodeStyleDetector::from_contents(&contents, &locator); - let mut generator: SourceCodeGenerator = (&stylist).into(); + let locator = Locator::new(&contents); + let stylist = Stylist::from_contents(&contents, &locator); + let mut generator: Generator = (&stylist).into(); generator.unparse_suite(&python_ast); println!("{}", generator.generate()); Ok(()) diff --git a/scripts/add_plugin.py b/scripts/add_plugin.py index a8d4565498..541d5813ee 100644 --- a/scripts/add_plugin.py +++ b/scripts/add_plugin.py @@ -34,7 +34,7 @@ def main(*, plugin: str, url: str) -> None: with open(os.path.join(ROOT_DIR, f"src/{dir_name(plugin)}/rules.rs"), "w+") as fp: fp.write("use crate::checkers::ast::Checker;\n") with open(os.path.join(ROOT_DIR, f"src/{dir_name(plugin)}/mod.rs"), "w+") as fp: - fp.write("pub mod rules;\n") + fp.write("pub(crate) mod rules;\n") fp.write("\n") fp.write( """#[cfg(test)] diff --git a/src/ast/helpers.rs b/src/ast/helpers.rs index c6c129687d..41164a09f8 100644 --- a/src/ast/helpers.rs +++ b/src/ast/helpers.rs @@ -12,9 +12,7 @@ use rustpython_parser::lexer::Tok; use rustpython_parser::token::StringKind; use crate::ast::types::{Binding, BindingKind, Range}; -use crate::source_code_generator::SourceCodeGenerator; -use crate::source_code_style::SourceCodeStyleDetector; -use crate::SourceCodeLocator; +use crate::source_code::{Generator, Locator, Stylist}; /// Create an `Expr` with default location from an `ExprKind`. pub fn create_expr(node: ExprKind) -> Expr { @@ -27,15 +25,15 @@ pub fn create_stmt(node: StmtKind) -> Stmt { } /// Generate source code from an `Expr`. -pub fn unparse_expr(expr: &Expr, stylist: &SourceCodeStyleDetector) -> String { - let mut generator: SourceCodeGenerator = stylist.into(); +pub fn unparse_expr(expr: &Expr, stylist: &Stylist) -> String { + let mut generator: Generator = stylist.into(); generator.unparse_expr(expr, 0); generator.generate() } /// Generate source code from an `Stmt`. -pub fn unparse_stmt(stmt: &Stmt, stylist: &SourceCodeStyleDetector) -> String { - let mut generator: SourceCodeGenerator = stylist.into(); +pub fn unparse_stmt(stmt: &Stmt, stylist: &Stylist) -> String { + let mut generator: Generator = stylist.into(); generator.unparse_stmt(stmt); generator.generate() } @@ -431,7 +429,7 @@ pub fn collect_arg_names<'a>(arguments: &'a Arguments) -> FxHashSet<&'a str> { } /// Returns `true` if a statement or expression includes at least one comment. -pub fn has_comments(located: &Located, locator: &SourceCodeLocator) -> bool { +pub fn has_comments(located: &Located, locator: &Locator) -> bool { lexer::make_tokenizer(&locator.slice_source_code_range(&Range::from_located(located))) .flatten() .any(|(_, tok, _)| matches!(tok, Tok::Comment(..))) @@ -483,14 +481,14 @@ pub fn to_absolute(relative: Location, base: Location) -> Location { } /// Return `true` if a `Stmt` has leading content. -pub fn match_leading_content(stmt: &Stmt, locator: &SourceCodeLocator) -> bool { +pub fn match_leading_content(stmt: &Stmt, locator: &Locator) -> bool { let range = Range::new(Location::new(stmt.location.row(), 0), stmt.location); let prefix = locator.slice_source_code_range(&range); prefix.chars().any(|char| !char.is_whitespace()) } /// Return `true` if a `Stmt` has trailing content. -pub fn match_trailing_content(stmt: &Stmt, locator: &SourceCodeLocator) -> bool { +pub fn match_trailing_content(stmt: &Stmt, locator: &Locator) -> bool { let range = Range::new( stmt.end_location.unwrap(), Location::new(stmt.end_location.unwrap().row() + 1, 0), @@ -508,7 +506,7 @@ pub fn match_trailing_content(stmt: &Stmt, locator: &SourceCodeLocator) -> bool } /// Return the number of trailing empty lines following a statement. -pub fn count_trailing_lines(stmt: &Stmt, locator: &SourceCodeLocator) -> usize { +pub fn count_trailing_lines(stmt: &Stmt, locator: &Locator) -> usize { let suffix = locator.slice_source_code_at(&Location::new(stmt.end_location.unwrap().row() + 1, 0)); suffix @@ -520,7 +518,7 @@ pub fn count_trailing_lines(stmt: &Stmt, locator: &SourceCodeLocator) -> usize { /// Return the appropriate visual `Range` for any message that spans a `Stmt`. /// Specifically, this method returns the range of a function or class name, /// rather than that of the entire function or class body. -pub fn identifier_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Range { +pub fn identifier_range(stmt: &Stmt, locator: &Locator) -> Range { if matches!( stmt.node, StmtKind::ClassDef { .. } @@ -539,7 +537,7 @@ pub fn identifier_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Range { } /// Like `identifier_range`, but accepts a `Binding`. -pub fn binding_range(binding: &Binding, locator: &SourceCodeLocator) -> Range { +pub fn binding_range(binding: &Binding, locator: &Locator) -> Range { if matches!( binding.kind, BindingKind::ClassDefinition | BindingKind::FunctionDefinition @@ -555,7 +553,7 @@ pub fn binding_range(binding: &Binding, locator: &SourceCodeLocator) -> Range { } // Return the ranges of `Name` tokens within a specified node. -pub fn find_names(located: &Located, locator: &SourceCodeLocator) -> Vec { +pub fn find_names(located: &Located, locator: &Locator) -> Vec { let contents = locator.slice_source_code_range(&Range::from_located(located)); lexer::make_tokenizer_located(&contents, located.location) .flatten() @@ -568,10 +566,7 @@ pub fn find_names(located: &Located, locator: &SourceCodeLocator) -> Vec Option { +pub fn excepthandler_name_range(handler: &Excepthandler, locator: &Locator) -> Option { let ExcepthandlerKind::ExceptHandler { name, type_, body, .. } = &handler.node; @@ -594,7 +589,7 @@ pub fn excepthandler_name_range( } /// Return the `Range` of `except` in `Excepthandler`. -pub fn except_range(handler: &Excepthandler, locator: &SourceCodeLocator) -> Range { +pub fn except_range(handler: &Excepthandler, locator: &Locator) -> Range { let ExcepthandlerKind::ExceptHandler { body, type_, .. } = &handler.node; let end = if let Some(type_) = type_ { type_.location @@ -619,7 +614,7 @@ pub fn except_range(handler: &Excepthandler, locator: &SourceCodeLocator) -> Ran } /// Find f-strings that don't contain any formatted values in a `JoinedStr`. -pub fn find_useless_f_strings(expr: &Expr, locator: &SourceCodeLocator) -> Vec<(Range, Range)> { +pub fn find_useless_f_strings(expr: &Expr, locator: &Locator) -> Vec<(Range, Range)> { let contents = locator.slice_source_code_range(&Range::from_located(expr)); lexer::make_tokenizer_located(&contents, expr.location) .flatten() @@ -656,7 +651,7 @@ pub fn find_useless_f_strings(expr: &Expr, locator: &SourceCodeLocator) -> Vec<( } /// Return the `Range` of `else` in `For`, `AsyncFor`, and `While` statements. -pub fn else_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Option { +pub fn else_range(stmt: &Stmt, locator: &Locator) -> Option { match &stmt.node { StmtKind::For { body, orelse, .. } | StmtKind::AsyncFor { body, orelse, .. } @@ -690,7 +685,7 @@ pub fn else_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Option { /// Return `true` if a `Stmt` appears to be part of a multi-statement line, with /// other statements preceding it. -pub fn preceded_by_continuation(stmt: &Stmt, locator: &SourceCodeLocator) -> bool { +pub fn preceded_by_continuation(stmt: &Stmt, locator: &Locator) -> bool { // Does the previous line end in a continuation? This will have a specific // false-positive, which is that if the previous line ends in a comment, it // will be treated as a continuation. So we should only use this information to @@ -711,13 +706,13 @@ pub fn preceded_by_continuation(stmt: &Stmt, locator: &SourceCodeLocator) -> boo /// Return `true` if a `Stmt` appears to be part of a multi-statement line, with /// other statements preceding it. -pub fn preceded_by_multi_statement_line(stmt: &Stmt, locator: &SourceCodeLocator) -> bool { +pub fn preceded_by_multi_statement_line(stmt: &Stmt, locator: &Locator) -> bool { match_leading_content(stmt, locator) || preceded_by_continuation(stmt, locator) } /// Return `true` if a `Stmt` appears to be part of a multi-statement line, with /// other statements following it. -pub fn followed_by_multi_statement_line(stmt: &Stmt, locator: &SourceCodeLocator) -> bool { +pub fn followed_by_multi_statement_line(stmt: &Stmt, locator: &Locator) -> bool { match_trailing_content(stmt, locator) } @@ -799,7 +794,7 @@ mod tests { else_range, identifier_range, match_module_member, match_trailing_content, }; use crate::ast::types::Range; - use crate::source_code_locator::SourceCodeLocator; + use crate::source_code::Locator; #[test] fn builtin() -> Result<()> { @@ -949,25 +944,25 @@ mod tests { let contents = "x = 1"; let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert!(!match_trailing_content(stmt, &locator)); let contents = "x = 1; y = 2"; let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert!(match_trailing_content(stmt, &locator)); let contents = "x = 1 "; let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert!(!match_trailing_content(stmt, &locator)); let contents = "x = 1 # Comment"; let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert!(!match_trailing_content(stmt, &locator)); let contents = r#" @@ -977,7 +972,7 @@ y = 2 .trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert!(!match_trailing_content(stmt, &locator)); Ok(()) @@ -988,7 +983,7 @@ y = 2 let contents = "def f(): pass".trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( identifier_range(stmt, &locator), Range::new(Location::new(1, 4), Location::new(1, 5),) @@ -1002,7 +997,7 @@ def \ .trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( identifier_range(stmt, &locator), Range::new(Location::new(2, 2), Location::new(2, 3),) @@ -1011,7 +1006,7 @@ def \ let contents = "class Class(): pass".trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( identifier_range(stmt, &locator), Range::new(Location::new(1, 6), Location::new(1, 11),) @@ -1020,7 +1015,7 @@ def \ let contents = "class Class: pass".trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( identifier_range(stmt, &locator), Range::new(Location::new(1, 6), Location::new(1, 11),) @@ -1034,7 +1029,7 @@ class Class(): .trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( identifier_range(stmt, &locator), Range::new(Location::new(2, 6), Location::new(2, 11),) @@ -1043,7 +1038,7 @@ class Class(): let contents = r#"x = y + 1"#.trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( identifier_range(stmt, &locator), Range::new(Location::new(1, 0), Location::new(1, 9),) @@ -1063,7 +1058,7 @@ else: .trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); let range = else_range(stmt, &locator).unwrap(); assert_eq!(range.location.row(), 3); assert_eq!(range.location.column(), 0); diff --git a/src/ast/types.rs b/src/ast/types.rs index 918902c9d0..e631e4a31c 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -74,7 +74,6 @@ pub enum ScopeKind<'a> { Function(FunctionDef<'a>), Generator, Module, - Arg, Lambda(Lambda<'a>), } diff --git a/src/autofix/fixer.rs b/src/autofix/fixer.rs index 9345c333ea..8b13789179 100644 --- a/src/autofix/fixer.rs +++ b/src/autofix/fixer.rs @@ -1,225 +1 @@ -use std::borrow::Cow; -use std::collections::BTreeSet; -use itertools::Itertools; -use ropey::RopeBuilder; -use rustpython_parser::ast::Location; - -use crate::ast::types::Range; -use crate::autofix::Fix; -use crate::registry::Diagnostic; -use crate::source_code_locator::SourceCodeLocator; - -#[derive(Debug, Copy, Clone, Hash)] -pub enum Mode { - Generate, - Apply, - Diff, - None, -} - -impl From for Mode { - fn from(value: bool) -> Self { - if value { - Mode::Apply - } else { - Mode::None - } - } -} - -/// Auto-fix errors in a file, and write the fixed source code to disk. -pub fn fix_file<'a>( - diagnostics: &'a [Diagnostic], - locator: &'a SourceCodeLocator<'a>, -) -> Option<(Cow<'a, str>, usize)> { - if diagnostics.iter().all(|check| check.fix.is_none()) { - return None; - } - - Some(apply_fixes( - diagnostics.iter().filter_map(|check| check.fix.as_ref()), - locator, - )) -} - -/// Apply a series of fixes. -fn apply_fixes<'a>( - fixes: impl Iterator, - locator: &'a SourceCodeLocator<'a>, -) -> (Cow<'a, str>, usize) { - let mut output = RopeBuilder::new(); - let mut last_pos: Location = Location::new(1, 0); - let mut applied: BTreeSet<&Fix> = BTreeSet::default(); - let mut num_fixed: usize = 0; - - for fix in fixes.sorted_by_key(|fix| fix.location) { - // If we already applied an identical fix as part of another correction, skip - // any re-application. - if applied.contains(&fix) { - num_fixed += 1; - continue; - } - - // Best-effort approach: if this fix overlaps with a fix we've already applied, - // skip it. - if last_pos > fix.location { - continue; - } - - // Add all contents from `last_pos` to `fix.location`. - let slice = locator.slice_source_code_range(&Range::new(last_pos, fix.location)); - output.append(&slice); - - // Add the patch itself. - output.append(&fix.content); - - // Track that the fix was applied. - last_pos = fix.end_location; - applied.insert(fix); - num_fixed += 1; - } - - // Add the remaining content. - let slice = locator.slice_source_code_at(&last_pos); - output.append(&slice); - - (Cow::from(output.finish()), num_fixed) -} - -#[cfg(test)] -mod tests { - use rustpython_parser::ast::Location; - - use crate::autofix::fixer::apply_fixes; - use crate::autofix::Fix; - use crate::SourceCodeLocator; - - #[test] - fn empty_file() { - let fixes = vec![]; - let locator = SourceCodeLocator::new(r#""#); - let (contents, fixed) = apply_fixes(fixes.iter(), &locator); - assert_eq!(contents, ""); - assert_eq!(fixed, 0); - } - - #[test] - fn apply_single_replacement() { - let fixes = vec![Fix { - content: "Bar".to_string(), - location: Location::new(1, 8), - end_location: Location::new(1, 14), - }]; - let locator = SourceCodeLocator::new( - r#" -class A(object): - ... -"# - .trim(), - ); - let (contents, fixed) = apply_fixes(fixes.iter(), &locator); - assert_eq!( - contents, - r#" -class A(Bar): - ... -"# - .trim(), - ); - assert_eq!(fixed, 1); - } - - #[test] - fn apply_single_removal() { - let fixes = vec![Fix { - content: String::new(), - location: Location::new(1, 7), - end_location: Location::new(1, 15), - }]; - let locator = SourceCodeLocator::new( - r#" -class A(object): - ... -"# - .trim(), - ); - let (contents, fixed) = apply_fixes(fixes.iter(), &locator); - assert_eq!( - contents, - r#" -class A: - ... -"# - .trim() - ); - assert_eq!(fixed, 1); - } - - #[test] - fn apply_double_removal() { - let fixes = vec![ - Fix { - content: String::new(), - location: Location::new(1, 7), - end_location: Location::new(1, 16), - }, - Fix { - content: String::new(), - location: Location::new(1, 16), - end_location: Location::new(1, 23), - }, - ]; - let locator = SourceCodeLocator::new( - r#" -class A(object, object): - ... -"# - .trim(), - ); - let (contents, fixed) = apply_fixes(fixes.iter(), &locator); - - assert_eq!( - contents, - r#" -class A: - ... -"# - .trim() - ); - assert_eq!(fixed, 2); - } - - #[test] - fn ignore_overlapping_fixes() { - let fixes = vec![ - Fix { - content: String::new(), - location: Location::new(1, 7), - end_location: Location::new(1, 15), - }, - Fix { - content: "ignored".to_string(), - location: Location::new(1, 9), - end_location: Location::new(1, 11), - }, - ]; - let locator = SourceCodeLocator::new( - r#" -class A(object): - ... -"# - .trim(), - ); - let (contents, fixed) = apply_fixes(fixes.iter(), &locator); - assert_eq!( - contents, - r#" -class A: - ... -"# - .trim(), - ); - assert_eq!(fixed, 1); - } -} diff --git a/src/autofix/helpers.rs b/src/autofix/helpers.rs index 03c66f0ab7..2f3724cc3c 100644 --- a/src/autofix/helpers.rs +++ b/src/autofix/helpers.rs @@ -9,10 +9,10 @@ use crate::ast::helpers; use crate::ast::helpers::to_absolute; use crate::ast::types::Range; use crate::ast::whitespace::LinesWithTrailingNewline; -use crate::autofix::Fix; use crate::cst::helpers::compose_module_path; use crate::cst::matchers::match_module; -use crate::source_code_locator::SourceCodeLocator; +use crate::fix::Fix; +use crate::source_code::Locator; /// Determine if a body contains only a single statement, taking into account /// deleted. @@ -78,7 +78,7 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result /// Return the location of a trailing semicolon following a `Stmt`, if it's part /// of a multi-statement line. -fn trailing_semicolon(stmt: &Stmt, locator: &SourceCodeLocator) -> Option { +fn trailing_semicolon(stmt: &Stmt, locator: &Locator) -> Option { let contents = locator.slice_source_code_at(&stmt.end_location.unwrap()); for (row, line) in LinesWithTrailingNewline::from(&contents).enumerate() { let trimmed = line.trim(); @@ -100,7 +100,7 @@ fn trailing_semicolon(stmt: &Stmt, locator: &SourceCodeLocator) -> Option Location { +fn next_stmt_break(semicolon: Location, locator: &Locator) -> Location { let start_location = Location::new(semicolon.row(), semicolon.column() + 1); let contents = locator.slice_source_code_at(&start_location); for (row, line) in LinesWithTrailingNewline::from(&contents).enumerate() { @@ -133,7 +133,7 @@ fn next_stmt_break(semicolon: Location, locator: &SourceCodeLocator) -> Location } /// Return `true` if a `Stmt` occurs at the end of a file. -fn is_end_of_file(stmt: &Stmt, locator: &SourceCodeLocator) -> bool { +fn is_end_of_file(stmt: &Stmt, locator: &Locator) -> bool { let contents = locator.slice_source_code_at(&stmt.end_location.unwrap()); contents.is_empty() } @@ -155,7 +155,7 @@ pub fn delete_stmt( stmt: &Stmt, parent: Option<&Stmt>, deleted: &[&Stmt], - locator: &SourceCodeLocator, + locator: &Locator, ) -> Result { if parent .map(|parent| is_lone_child(stmt, parent, deleted)) @@ -197,7 +197,7 @@ pub fn remove_unused_imports<'a>( stmt: &Stmt, parent: Option<&Stmt>, deleted: &[&Stmt], - locator: &SourceCodeLocator, + locator: &Locator, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(stmt)); let mut tree = match_module(&module_text)?; @@ -299,20 +299,20 @@ mod tests { use rustpython_parser::parser; use crate::autofix::helpers::{next_stmt_break, trailing_semicolon}; - use crate::source_code_locator::SourceCodeLocator; + use crate::source_code::Locator; #[test] fn find_semicolon() -> Result<()> { let contents = "x = 1"; let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!(trailing_semicolon(stmt, &locator), None); let contents = "x = 1; y = 1"; let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( trailing_semicolon(stmt, &locator), Some(Location::new(1, 5)) @@ -321,7 +321,7 @@ mod tests { let contents = "x = 1 ; y = 1"; let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( trailing_semicolon(stmt, &locator), Some(Location::new(1, 6)) @@ -334,7 +334,7 @@ x = 1 \ .trim(); let program = parser::parse_program(contents, "")?; let stmt = program.first().unwrap(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( trailing_semicolon(stmt, &locator), Some(Location::new(2, 2)) @@ -346,14 +346,14 @@ x = 1 \ #[test] fn find_next_stmt_break() { let contents = "x = 1; y = 1"; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( next_stmt_break(Location::new(1, 4), &locator), Location::new(1, 5) ); let contents = "x = 1 ; y = 1"; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( next_stmt_break(Location::new(1, 5), &locator), Location::new(1, 6) @@ -364,7 +364,7 @@ x = 1 \ ; y = 1 "# .trim(); - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( next_stmt_break(Location::new(2, 2), &locator), Location::new(2, 4) diff --git a/src/autofix/mod.rs b/src/autofix/mod.rs index 3033c4a350..3f70689213 100644 --- a/src/autofix/mod.rs +++ b/src/autofix/mod.rs @@ -1,38 +1,210 @@ +use std::borrow::Cow; +use std::collections::BTreeSet; + +use itertools::Itertools; +use ropey::RopeBuilder; use rustpython_ast::Location; -use serde::{Deserialize, Serialize}; + +use crate::ast::types::Range; +use crate::fix::Fix; +use crate::registry::Diagnostic; +use crate::source_code::Locator; pub mod fixer; pub mod helpers; -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] -pub struct Fix { - pub content: String, - pub location: Location, - pub end_location: Location, +/// Auto-fix errors in a file, and write the fixed source code to disk. +pub fn fix_file<'a>( + diagnostics: &'a [Diagnostic], + locator: &'a Locator<'a>, +) -> Option<(Cow<'a, str>, usize)> { + if diagnostics.iter().all(|check| check.fix.is_none()) { + return None; + } + + Some(apply_fixes( + diagnostics.iter().filter_map(|check| check.fix.as_ref()), + locator, + )) } -impl Fix { - pub fn deletion(start: Location, end: Location) -> Self { - Self { +/// Apply a series of fixes. +fn apply_fixes<'a>( + fixes: impl Iterator, + locator: &'a Locator<'a>, +) -> (Cow<'a, str>, usize) { + let mut output = RopeBuilder::new(); + let mut last_pos: Location = Location::new(1, 0); + let mut applied: BTreeSet<&Fix> = BTreeSet::default(); + let mut num_fixed: usize = 0; + + for fix in fixes.sorted_by_key(|fix| fix.location) { + // If we already applied an identical fix as part of another correction, skip + // any re-application. + if applied.contains(&fix) { + num_fixed += 1; + continue; + } + + // Best-effort approach: if this fix overlaps with a fix we've already applied, + // skip it. + if last_pos > fix.location { + continue; + } + + // Add all contents from `last_pos` to `fix.location`. + let slice = locator.slice_source_code_range(&Range::new(last_pos, fix.location)); + output.append(&slice); + + // Add the patch itself. + output.append(&fix.content); + + // Track that the fix was applied. + last_pos = fix.end_location; + applied.insert(fix); + num_fixed += 1; + } + + // Add the remaining content. + let slice = locator.slice_source_code_at(&last_pos); + output.append(&slice); + + (Cow::from(output.finish()), num_fixed) +} + +#[cfg(test)] +mod tests { + use rustpython_parser::ast::Location; + + use crate::autofix::apply_fixes; + use crate::fix::Fix; + use crate::source_code::Locator; + + #[test] + fn empty_file() { + let fixes = vec![]; + let locator = Locator::new(r#""#); + let (contents, fixed) = apply_fixes(fixes.iter(), &locator); + assert_eq!(contents, ""); + assert_eq!(fixed, 0); + } + + #[test] + fn apply_single_replacement() { + let fixes = vec![Fix { + content: "Bar".to_string(), + location: Location::new(1, 8), + end_location: Location::new(1, 14), + }]; + let locator = Locator::new( + r#" +class A(object): + ... +"# + .trim(), + ); + let (contents, fixed) = apply_fixes(fixes.iter(), &locator); + assert_eq!( + contents, + r#" +class A(Bar): + ... +"# + .trim(), + ); + assert_eq!(fixed, 1); + } + + #[test] + fn apply_single_removal() { + let fixes = vec![Fix { content: String::new(), - location: start, - end_location: end, - } + location: Location::new(1, 7), + end_location: Location::new(1, 15), + }]; + let locator = Locator::new( + r#" +class A(object): + ... +"# + .trim(), + ); + let (contents, fixed) = apply_fixes(fixes.iter(), &locator); + assert_eq!( + contents, + r#" +class A: + ... +"# + .trim() + ); + assert_eq!(fixed, 1); } - pub fn replacement(content: String, start: Location, end: Location) -> Self { - Self { - content, - location: start, - end_location: end, - } + #[test] + fn apply_double_removal() { + let fixes = vec![ + Fix { + content: String::new(), + location: Location::new(1, 7), + end_location: Location::new(1, 16), + }, + Fix { + content: String::new(), + location: Location::new(1, 16), + end_location: Location::new(1, 23), + }, + ]; + let locator = Locator::new( + r#" +class A(object, object): + ... +"# + .trim(), + ); + let (contents, fixed) = apply_fixes(fixes.iter(), &locator); + + assert_eq!( + contents, + r#" +class A: + ... +"# + .trim() + ); + assert_eq!(fixed, 2); } - pub fn insertion(content: String, at: Location) -> Self { - Self { - content, - location: at, - end_location: at, - } + #[test] + fn ignore_overlapping_fixes() { + let fixes = vec![ + Fix { + content: String::new(), + location: Location::new(1, 7), + end_location: Location::new(1, 15), + }, + Fix { + content: "ignored".to_string(), + location: Location::new(1, 9), + end_location: Location::new(1, 11), + }, + ]; + let locator = Locator::new( + r#" +class A(object): + ... +"# + .trim(), + ); + let (contents, fixed) = apply_fixes(fixes.iter(), &locator); + assert_eq!( + contents, + r#" +class A: + ... +"# + .trim(), + ); + assert_eq!(fixed, 1); } } diff --git a/src/cache.rs b/src/cache.rs index 2eab3a66f1..1ec0caa21e 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -53,6 +53,7 @@ fn cache_key>(path: P, settings: &Settings, autofix: flags::Autof hasher.finish() } +#[allow(dead_code)] /// Initialize the cache at the specified `Path`. pub fn init(path: &Path) -> Result<()> { // Create the cache directories. diff --git a/src/checkers/ast.rs b/src/checkers/ast.rs index f3c8870b28..5a1a796c20 100644 --- a/src/checkers/ast.rs +++ b/src/checkers/ast.rs @@ -33,8 +33,7 @@ use crate::python::typing::SubscriptKind; use crate::registry::{Diagnostic, RuleCode}; use crate::settings::types::PythonVersion; use crate::settings::{flags, Settings}; -use crate::source_code_locator::SourceCodeLocator; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::{Locator, Stylist}; use crate::violations::DeferralKeyword; use crate::visibility::{module_visibility, transition_scope, Modifier, Visibility, VisibleScope}; use crate::{ @@ -59,8 +58,8 @@ pub struct Checker<'a> { noqa: flags::Noqa, pub(crate) settings: &'a Settings, pub(crate) noqa_line_for: &'a IntMap, - pub(crate) locator: &'a SourceCodeLocator<'a>, - pub(crate) style: &'a SourceCodeStyleDetector<'a>, + pub(crate) locator: &'a Locator<'a>, + pub(crate) style: &'a Stylist<'a>, // Computed diagnostics. pub(crate) diagnostics: Vec, // Function and class definition tracking (e.g., for docstring enforcement). @@ -110,8 +109,8 @@ impl<'a> Checker<'a> { autofix: flags::Autofix, noqa: flags::Noqa, path: &'a Path, - locator: &'a SourceCodeLocator, - style: &'a SourceCodeStyleDetector, + locator: &'a Locator, + style: &'a Stylist, ) -> Checker<'a> { Checker { settings, @@ -3238,16 +3237,6 @@ impl<'a> Checker<'a> { self.parents.iter().rev().nth(1) } - /// Return the grandparent `Stmt` of the current `Stmt`, if any. - pub fn current_stmt_grandparent(&self) -> Option<&RefEquality<'a, Stmt>> { - self.parents.iter().rev().nth(2) - } - - /// Return the current `Expr`. - pub fn current_expr(&self) -> Option<&RefEquality<'a, Expr>> { - self.exprs.iter().rev().next() - } - /// Return the parent `Expr` of the current `Expr`. pub fn current_expr_parent(&self) -> Option<&RefEquality<'a, Expr>> { self.exprs.iter().rev().nth(1) @@ -4308,8 +4297,8 @@ impl<'a> Checker<'a> { #[allow(clippy::too_many_arguments)] pub fn check_ast( python_ast: &Suite, - locator: &SourceCodeLocator, - stylist: &SourceCodeStyleDetector, + locator: &Locator, + stylist: &Stylist, noqa_line_for: &IntMap, settings: &Settings, autofix: flags::Autofix, diff --git a/src/checkers/imports.rs b/src/checkers/imports.rs index 6a74ea12c9..f3586325a3 100644 --- a/src/checkers/imports.rs +++ b/src/checkers/imports.rs @@ -10,16 +10,15 @@ use crate::isort; use crate::isort::track::{Block, ImportTracker}; use crate::registry::{Diagnostic, RuleCode}; use crate::settings::{flags, Settings}; -use crate::source_code_locator::SourceCodeLocator; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::{Locator, Stylist}; #[allow(clippy::too_many_arguments)] pub fn check_imports( python_ast: &Suite, - locator: &SourceCodeLocator, + locator: &Locator, directives: &IsortDirectives, settings: &Settings, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, autofix: flags::Autofix, path: &Path, package: Option<&Path>, diff --git a/src/checkers/noqa.rs b/src/checkers/noqa.rs index 7c21670933..de8fd9db1e 100644 --- a/src/checkers/noqa.rs +++ b/src/checkers/noqa.rs @@ -6,7 +6,7 @@ use nohash_hasher::IntMap; use rustpython_parser::ast::Location; use crate::ast::types::Range; -use crate::autofix::Fix; +use crate::fix::Fix; use crate::noqa::{is_file_exempt, Directive}; use crate::registry::{Diagnostic, DiagnosticKind, RuleCode, CODE_REDIRECTS}; use crate::settings::{flags, Settings}; diff --git a/src/checkers/tokens.rs b/src/checkers/tokens.rs index 94b85c87f5..d436375f36 100644 --- a/src/checkers/tokens.rs +++ b/src/checkers/tokens.rs @@ -5,12 +5,12 @@ use rustpython_parser::lexer::{LexResult, Tok}; use crate::lex::docstring_detection::StateMachine; use crate::registry::{Diagnostic, RuleCode}; use crate::ruff::rules::Context; -use crate::settings::flags; -use crate::source_code_locator::SourceCodeLocator; -use crate::{eradicate, flake8_implicit_str_concat, flake8_quotes, pycodestyle, ruff, Settings}; +use crate::settings::{flags, Settings}; +use crate::source_code::Locator; +use crate::{eradicate, flake8_implicit_str_concat, flake8_quotes, pycodestyle, ruff}; pub fn check_tokens( - locator: &SourceCodeLocator, + locator: &Locator, tokens: &[LexResult], settings: &Settings, autofix: flags::Autofix, diff --git a/src/commands.rs b/src/commands.rs index 52bfa18160..ad3de3b4f3 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -15,7 +15,6 @@ use rustpython_ast::Location; use serde::Serialize; use walkdir::WalkDir; -use crate::autofix::fixer; use crate::cache::CACHE_DIR_NAME; use crate::cli::Overrides; use crate::iterators::par_iter; @@ -26,7 +25,7 @@ use crate::registry::RuleCode; use crate::resolver::{FileDiscovery, PyprojectDiscovery}; use crate::settings::flags; use crate::settings::types::SerializationFormat; -use crate::{cache, fs, packages, resolver, violations, warn_user_once}; +use crate::{cache, fix, fs, packaging, resolver, violations, warn_user_once}; /// Run the linter over a collection of files. pub fn run( @@ -35,7 +34,7 @@ pub fn run( file_strategy: &FileDiscovery, overrides: &Overrides, cache: flags::Cache, - autofix: fixer::Mode, + autofix: fix::FixMode, ) -> Result { // Collect all the Python files to check. let start = Instant::now(); @@ -77,7 +76,7 @@ pub fn run( }; // Discover the package root for each Python file. - let package_roots = packages::detect_package_roots( + let package_roots = packaging::detect_package_roots( &paths .iter() .flatten() @@ -156,7 +155,7 @@ pub fn run_stdin( pyproject_strategy: &PyprojectDiscovery, file_strategy: &FileDiscovery, overrides: &Overrides, - autofix: fixer::Mode, + autofix: fix::FixMode, ) -> Result { if let Some(filename) = filename { if !resolver::python_file_at_path(filename, pyproject_strategy, file_strategy, overrides)? { @@ -169,7 +168,7 @@ pub fn run_stdin( }; let package_root = filename .and_then(Path::parent) - .and_then(packages::detect_package_root); + .and_then(packaging::detect_package_root); let stdin = read_from_stdin()?; let mut diagnostics = lint_stdin(filename, package_root, &stdin, settings, autofix)?; diagnostics.messages.sort_unstable(); diff --git a/src/directives.rs b/src/directives.rs index 33275ab3b5..264e8ca75d 100644 --- a/src/directives.rs +++ b/src/directives.rs @@ -6,7 +6,7 @@ use rustpython_ast::Location; use rustpython_parser::lexer::{LexResult, Tok}; use crate::registry::LintSource; -use crate::Settings; +use crate::settings::Settings; bitflags! { pub struct Flags: u32 { diff --git a/src/eradicate/mod.rs b/src/eradicate/mod.rs index e611107fb5..b1809c04d3 100644 --- a/src/eradicate/mod.rs +++ b/src/eradicate/mod.rs @@ -1,5 +1,5 @@ -pub mod detection; -pub mod rules; +pub(crate) mod detection; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/eradicate/rules.rs b/src/eradicate/rules.rs index 1d5a8a8b09..b3f1872d1e 100644 --- a/src/eradicate/rules.rs +++ b/src/eradicate/rules.rs @@ -1,11 +1,12 @@ use rustpython_ast::Location; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::eradicate::detection::comment_contains_code; -use crate::registry::RuleCode; -use crate::settings::flags; -use crate::{violations, Diagnostic, Settings, SourceCodeLocator}; +use crate::fix::Fix; +use crate::registry::{Diagnostic, RuleCode}; +use crate::settings::{flags, Settings}; +use crate::source_code::Locator; +use crate::violations; fn is_standalone_comment(line: &str) -> bool { for char in line.chars() { @@ -20,7 +21,7 @@ fn is_standalone_comment(line: &str) -> bool { /// ERA001 pub fn commented_out_code( - locator: &SourceCodeLocator, + locator: &Locator, start: Location, end: Location, settings: &Settings, diff --git a/src/fix.rs b/src/fix.rs new file mode 100644 index 0000000000..7827bddc92 --- /dev/null +++ b/src/fix.rs @@ -0,0 +1,53 @@ +use rustpython_ast::Location; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Copy, Clone, Hash)] +pub enum FixMode { + Generate, + Apply, + Diff, + None, +} + +impl From for FixMode { + fn from(value: bool) -> Self { + if value { + FixMode::Apply + } else { + FixMode::None + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct Fix { + pub content: String, + pub location: Location, + pub end_location: Location, +} + +impl Fix { + pub fn deletion(start: Location, end: Location) -> Self { + Self { + content: String::new(), + location: start, + end_location: end, + } + } + + pub fn replacement(content: String, start: Location, end: Location) -> Self { + Self { + content, + location: start, + end_location: end, + } + } + + pub fn insertion(content: String, at: Location) -> Self { + Self { + content, + location: at, + end_location: at, + } + } +} diff --git a/src/flake8_2020/mod.rs b/src/flake8_2020/mod.rs index abc8807f60..6b8d250fba 100644 --- a/src/flake8_2020/mod.rs +++ b/src/flake8_2020/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_annotations/fixes.rs b/src/flake8_annotations/fixes.rs index ce826693e0..b337d4687a 100644 --- a/src/flake8_annotations/fixes.rs +++ b/src/flake8_annotations/fixes.rs @@ -4,11 +4,11 @@ use rustpython_parser::lexer; use rustpython_parser::lexer::Tok; use crate::ast::types::Range; -use crate::autofix::Fix; -use crate::source_code_locator::SourceCodeLocator; +use crate::fix::Fix; +use crate::source_code::Locator; /// ANN204 -pub fn add_return_none_annotation(locator: &SourceCodeLocator, stmt: &Stmt) -> Result { +pub fn add_return_none_annotation(locator: &Locator, stmt: &Stmt) -> Result { let range = Range::from_located(stmt); let contents = locator.slice_source_code_range(&range); diff --git a/src/flake8_annotations/mod.rs b/src/flake8_annotations/mod.rs index d8278251cc..0395dc1048 100644 --- a/src/flake8_annotations/mod.rs +++ b/src/flake8_annotations/mod.rs @@ -1,6 +1,6 @@ mod fixes; -pub mod helpers; -pub mod rules; +pub(crate) mod helpers; +pub(crate) mod rules; pub mod settings; #[cfg(test)] @@ -9,9 +9,10 @@ mod tests { use anyhow::Result; + use crate::flake8_annotations; use crate::linter::test_path; use crate::registry::RuleCode; - use crate::{flake8_annotations, Settings}; + use crate::settings::Settings; #[test] fn defaults() -> Result<()> { diff --git a/src/flake8_annotations/rules.rs b/src/flake8_annotations/rules.rs index 78151340d1..06bc452477 100644 --- a/src/flake8_annotations/rules.rs +++ b/src/flake8_annotations/rules.rs @@ -8,9 +8,9 @@ use crate::checkers::ast::Checker; use crate::docstrings::definition::{Definition, DefinitionKind}; use crate::flake8_annotations::fixes; use crate::flake8_annotations::helpers::match_function_def; -use crate::registry::RuleCode; +use crate::registry::{Diagnostic, RuleCode}; use crate::visibility::Visibility; -use crate::{violations, visibility, Diagnostic}; +use crate::{violations, visibility}; #[derive(Default)] struct ReturnStatementVisitor<'a> { diff --git a/src/flake8_bandit/mod.rs b/src/flake8_bandit/mod.rs index d3681fb4d0..33de022177 100644 --- a/src/flake8_bandit/mod.rs +++ b/src/flake8_bandit/mod.rs @@ -1,5 +1,5 @@ mod helpers; -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] @@ -9,9 +9,10 @@ mod tests { use anyhow::Result; use test_case::test_case; + use crate::flake8_bandit; use crate::linter::test_path; use crate::registry::RuleCode; - use crate::{flake8_bandit, Settings}; + use crate::settings::Settings; #[test_case(RuleCode::S101, Path::new("S101.py"); "S101")] #[test_case(RuleCode::S102, Path::new("S102.py"); "S102")] diff --git a/src/flake8_blind_except/mod.rs b/src/flake8_blind_except/mod.rs index 1ef8d92f39..914d17df4f 100644 --- a/src/flake8_blind_except/mod.rs +++ b/src/flake8_blind_except/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_boolean_trap/mod.rs b/src/flake8_boolean_trap/mod.rs index 5e64a2112f..194dc17023 100644 --- a/src/flake8_boolean_trap/mod.rs +++ b/src/flake8_boolean_trap/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_bugbear/mod.rs b/src/flake8_bugbear/mod.rs index 0f55196094..dbea0cc2f8 100644 --- a/src/flake8_bugbear/mod.rs +++ b/src/flake8_bugbear/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] @@ -8,9 +8,10 @@ mod tests { use anyhow::Result; use test_case::test_case; + use crate::flake8_bugbear; use crate::linter::test_path; use crate::registry::RuleCode; - use crate::{flake8_bugbear, Settings}; + use crate::settings::Settings; #[test_case(RuleCode::B002, Path::new("B002.py"); "B002")] #[test_case(RuleCode::B003, Path::new("B003.py"); "B003")] diff --git a/src/flake8_bugbear/rules/assert_false.rs b/src/flake8_bugbear/rules/assert_false.rs index 4622e22773..323532e73a 100644 --- a/src/flake8_bugbear/rules/assert_false.rs +++ b/src/flake8_bugbear/rules/assert_false.rs @@ -1,10 +1,10 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Location, Stmt, StmtKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; -use crate::source_code_generator::SourceCodeGenerator; +use crate::source_code::Generator; use crate::violations; fn assertion_error(msg: Option<&Expr>) -> Stmt { @@ -48,7 +48,7 @@ pub fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: Option let mut diagnostic = Diagnostic::new(violations::DoNotAssertFalse, Range::from_located(test)); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_stmt(&assertion_error(msg)); diagnostic.amend(Fix::replacement( generator.generate(), diff --git a/src/flake8_bugbear/rules/duplicate_exceptions.rs b/src/flake8_bugbear/rules/duplicate_exceptions.rs index 57c519b966..1f0d0e084a 100644 --- a/src/flake8_bugbear/rules/duplicate_exceptions.rs +++ b/src/flake8_bugbear/rules/duplicate_exceptions.rs @@ -4,10 +4,10 @@ use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKi use crate::ast::helpers; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; -use crate::source_code_generator::SourceCodeGenerator; +use crate::source_code::Generator; use crate::violations; fn type_pattern(elts: Vec<&Expr>) -> Expr { @@ -55,7 +55,7 @@ fn duplicate_handler_exceptions<'a>( Range::from_located(expr), ); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); if unique_elts.len() == 1 { generator.unparse_expr(unique_elts[0], 0); } else { diff --git a/src/flake8_bugbear/rules/getattr_with_constant.rs b/src/flake8_bugbear/rules/getattr_with_constant.rs index 6b624266cb..9a4a6dae82 100644 --- a/src/flake8_bugbear/rules/getattr_with_constant.rs +++ b/src/flake8_bugbear/rules/getattr_with_constant.rs @@ -1,12 +1,12 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Location}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::python::identifiers::IDENTIFIER_REGEX; use crate::python::keyword::KWLIST; use crate::registry::Diagnostic; -use crate::source_code_generator::SourceCodeGenerator; +use crate::source_code::Generator; use crate::violations; fn attribute(value: &Expr, attr: &str) -> Expr { @@ -48,7 +48,7 @@ pub fn getattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar let mut diagnostic = Diagnostic::new(violations::GetAttrWithConstant, Range::from_located(expr)); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr(&attribute(obj, value), 0); diagnostic.amend(Fix::replacement( generator.generate(), diff --git a/src/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs b/src/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs index 4773112412..3ed870eca6 100644 --- a/src/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs +++ b/src/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs @@ -1,10 +1,10 @@ use rustpython_ast::{Excepthandler, ExcepthandlerKind, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; -use crate::source_code_generator::SourceCodeGenerator; +use crate::source_code::Generator; use crate::violations; /// B013 @@ -24,7 +24,7 @@ pub fn redundant_tuple_in_exception_handler(checker: &mut Checker, handlers: &[E Range::from_located(type_), ); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr(elt, 0); diagnostic.amend(Fix::replacement( generator.generate(), diff --git a/src/flake8_bugbear/rules/setattr_with_constant.rs b/src/flake8_bugbear/rules/setattr_with_constant.rs index c7f876874d..21de18dc02 100644 --- a/src/flake8_bugbear/rules/setattr_with_constant.rs +++ b/src/flake8_bugbear/rules/setattr_with_constant.rs @@ -1,16 +1,15 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Location, Stmt, StmtKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::python::identifiers::IDENTIFIER_REGEX; use crate::python::keyword::KWLIST; use crate::registry::Diagnostic; -use crate::source_code_generator::SourceCodeGenerator; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::{Generator, Stylist}; use crate::violations; -fn assignment(obj: &Expr, name: &str, value: &Expr, stylist: &SourceCodeStyleDetector) -> String { +fn assignment(obj: &Expr, name: &str, value: &Expr, stylist: &Stylist) -> String { let stmt = Stmt::new( Location::default(), Location::default(), @@ -28,7 +27,7 @@ fn assignment(obj: &Expr, name: &str, value: &Expr, stylist: &SourceCodeStyleDet type_comment: None, }, ); - let mut generator: SourceCodeGenerator = stylist.into(); + let mut generator: Generator = stylist.into(); generator.unparse_stmt(&stmt); generator.generate() } diff --git a/src/flake8_bugbear/rules/unused_loop_control_variable.rs b/src/flake8_bugbear/rules/unused_loop_control_variable.rs index b925cf2a25..dea062c702 100644 --- a/src/flake8_bugbear/rules/unused_loop_control_variable.rs +++ b/src/flake8_bugbear/rules/unused_loop_control_variable.rs @@ -4,8 +4,8 @@ use rustpython_ast::{Expr, ExprKind, Stmt}; use crate::ast::types::Range; use crate::ast::visitor; use crate::ast::visitor::Visitor; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/flake8_builtins/mod.rs b/src/flake8_builtins/mod.rs index 622923312e..94db607c2b 100644 --- a/src/flake8_builtins/mod.rs +++ b/src/flake8_builtins/mod.rs @@ -1,5 +1,5 @@ -pub mod rules; -pub mod types; +pub(crate) mod rules; +pub(crate) mod types; #[cfg(test)] mod tests { diff --git a/src/flake8_comprehensions/fixes.rs b/src/flake8_comprehensions/fixes.rs index 03becbc411..b94b280fdd 100644 --- a/src/flake8_comprehensions/fixes.rs +++ b/src/flake8_comprehensions/fixes.rs @@ -7,9 +7,9 @@ use libcst_native::{ }; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::cst::matchers::{match_expr, match_module}; -use crate::source_code_locator::SourceCodeLocator; +use crate::fix::Fix; +use crate::source_code::Locator; fn match_call<'a, 'b>(expr: &'a mut Expr<'b>) -> Result<&'a mut Call<'b>> { if let Expression::Call(call) = &mut expr.value { @@ -29,7 +29,7 @@ fn match_arg<'a, 'b>(call: &'a Call<'b>) -> Result<&'a Arg<'b>> { /// (C400) Convert `list(x for x in y)` to `[x for x in y]`. pub fn fix_unnecessary_generator_list( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { // Expr(Call(GeneratorExp)))) -> Expr(ListComp))) @@ -70,7 +70,7 @@ pub fn fix_unnecessary_generator_list( /// (C401) Convert `set(x for x in y)` to `{x for x in y}`. pub fn fix_unnecessary_generator_set( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { // Expr(Call(GeneratorExp)))) -> Expr(SetComp))) @@ -112,7 +112,7 @@ pub fn fix_unnecessary_generator_set( /// (C402) Convert `dict((x, x) for x in range(3))` to `{x: x for x in /// range(3)}`. pub fn fix_unnecessary_generator_dict( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(expr)); @@ -169,7 +169,7 @@ pub fn fix_unnecessary_generator_dict( /// (C403) Convert `set([x for x in y])` to `{x for x in y}`. pub fn fix_unnecessary_list_comprehension_set( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { // Expr(Call(ListComp)))) -> @@ -210,7 +210,7 @@ pub fn fix_unnecessary_list_comprehension_set( /// (C404) Convert `dict([(i, i) for i in range(3)])` to `{i: i for i in /// range(3)}`. pub fn fix_unnecessary_list_comprehension_dict( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(expr)); @@ -259,10 +259,7 @@ pub fn fix_unnecessary_list_comprehension_dict( } /// (C405) Convert `set((1, 2))` to `{1, 2}`. -pub fn fix_unnecessary_literal_set( - locator: &SourceCodeLocator, - expr: &rustpython_ast::Expr, -) -> Result { +pub fn fix_unnecessary_literal_set(locator: &Locator, expr: &rustpython_ast::Expr) -> Result { // Expr(Call(List|Tuple)))) -> Expr(Set))) let module_text = locator.slice_source_code_range(&Range::from_located(expr)); let mut tree = match_module(&module_text)?; @@ -305,10 +302,7 @@ pub fn fix_unnecessary_literal_set( } /// (C406) Convert `dict([(1, 2)])` to `{1: 2}`. -pub fn fix_unnecessary_literal_dict( - locator: &SourceCodeLocator, - expr: &rustpython_ast::Expr, -) -> Result { +pub fn fix_unnecessary_literal_dict(locator: &Locator, expr: &rustpython_ast::Expr) -> Result { // Expr(Call(List|Tuple)))) -> Expr(Dict))) let module_text = locator.slice_source_code_range(&Range::from_located(expr)); let mut tree = match_module(&module_text)?; @@ -374,7 +368,7 @@ pub fn fix_unnecessary_literal_dict( /// (C408) pub fn fix_unnecessary_collection_call( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { // Expr(Call("list" | "tuple" | "dict")))) -> Expr(List|Tuple|Dict) @@ -483,7 +477,7 @@ pub fn fix_unnecessary_collection_call( /// (C409) Convert `tuple([1, 2])` to `tuple(1, 2)` pub fn fix_unnecessary_literal_within_tuple_call( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(expr)); @@ -537,7 +531,7 @@ pub fn fix_unnecessary_literal_within_tuple_call( /// (C410) Convert `list([1, 2])` to `[1, 2]` pub fn fix_unnecessary_literal_within_list_call( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(expr)); @@ -592,10 +586,7 @@ pub fn fix_unnecessary_literal_within_list_call( } /// (C411) Convert `list([i * i for i in x])` to `[i * i for i in x]`. -pub fn fix_unnecessary_list_call( - locator: &SourceCodeLocator, - expr: &rustpython_ast::Expr, -) -> Result { +pub fn fix_unnecessary_list_call(locator: &Locator, expr: &rustpython_ast::Expr) -> Result { // Expr(Call(List|Tuple)))) -> Expr(List|Tuple))) let module_text = locator.slice_source_code_range(&Range::from_located(expr)); let mut tree = match_module(&module_text)?; @@ -619,7 +610,7 @@ pub fn fix_unnecessary_list_call( /// (C413) Convert `reversed(sorted([2, 3, 1]))` to `sorted([2, 3, 1], /// reverse=True)`. pub fn fix_unnecessary_call_around_sorted( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(expr)); @@ -701,7 +692,7 @@ pub fn fix_unnecessary_call_around_sorted( /// (C416) Convert `[i for i in x]` to `list(x)`. pub fn fix_unnecessary_comprehension( - locator: &SourceCodeLocator, + locator: &Locator, expr: &rustpython_ast::Expr, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(expr)); diff --git a/src/flake8_comprehensions/mod.rs b/src/flake8_comprehensions/mod.rs index 11a7189972..bda3c8d251 100644 --- a/src/flake8_comprehensions/mod.rs +++ b/src/flake8_comprehensions/mod.rs @@ -1,5 +1,5 @@ mod fixes; -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_datetimez/mod.rs b/src/flake8_datetimez/mod.rs index a184ab28e8..bdfb34ef05 100644 --- a/src/flake8_datetimez/mod.rs +++ b/src/flake8_datetimez/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_debugger/mod.rs b/src/flake8_debugger/mod.rs index 234832ac60..4c25641b35 100644 --- a/src/flake8_debugger/mod.rs +++ b/src/flake8_debugger/mod.rs @@ -1,5 +1,5 @@ -pub mod rules; -pub mod types; +pub(crate) mod rules; +pub(crate) mod types; #[cfg(test)] mod tests { diff --git a/src/flake8_errmsg/mod.rs b/src/flake8_errmsg/mod.rs index 5c16749d57..ef829ae1b5 100644 --- a/src/flake8_errmsg/mod.rs +++ b/src/flake8_errmsg/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] diff --git a/src/flake8_implicit_str_concat/mod.rs b/src/flake8_implicit_str_concat/mod.rs index 43b0f8b7dc..635db9a236 100644 --- a/src/flake8_implicit_str_concat/mod.rs +++ b/src/flake8_implicit_str_concat/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_implicit_str_concat/rules.rs b/src/flake8_implicit_str_concat/rules.rs index c1e8184d41..93dd7f269f 100644 --- a/src/flake8_implicit_str_concat/rules.rs +++ b/src/flake8_implicit_str_concat/rules.rs @@ -4,11 +4,11 @@ use rustpython_parser::lexer::{LexResult, Tok}; use crate::ast::types::Range; use crate::registry::Diagnostic; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; /// ISC001, ISC002 -pub fn implicit(tokens: &[LexResult], locator: &SourceCodeLocator) -> Vec { +pub fn implicit(tokens: &[LexResult], locator: &Locator) -> Vec { let mut diagnostics = vec![]; for ((a_start, a_tok, a_end), (b_start, b_tok, b_end)) in tokens.iter().flatten().tuple_windows() diff --git a/src/flake8_import_conventions/mod.rs b/src/flake8_import_conventions/mod.rs index e475c28695..31a4a45fcb 100644 --- a/src/flake8_import_conventions/mod.rs +++ b/src/flake8_import_conventions/mod.rs @@ -1,17 +1,17 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] mod tests { - use std::path::Path; use anyhow::Result; use rustc_hash::FxHashMap; + use crate::flake8_import_conventions; use crate::linter::test_path; use crate::registry::RuleCode; - use crate::{flake8_import_conventions, Settings}; + use crate::settings::Settings; #[test] fn defaults() -> Result<()> { diff --git a/src/flake8_pie/mod.rs b/src/flake8_pie/mod.rs index 085207e925..754e274a88 100644 --- a/src/flake8_pie/mod.rs +++ b/src/flake8_pie/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_pie/rules.rs b/src/flake8_pie/rules.rs index 3a611c7edf..209ed3ef1e 100644 --- a/src/flake8_pie/rules.rs +++ b/src/flake8_pie/rules.rs @@ -4,8 +4,8 @@ use rustpython_ast::{Constant, Expr, ExprKind, Stmt, StmtKind}; use crate::ast::types::{Range, RefEquality}; use crate::autofix::helpers::delete_stmt; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/flake8_print/mod.rs b/src/flake8_print/mod.rs index 9ed5e30716..75fd5948f7 100644 --- a/src/flake8_print/mod.rs +++ b/src/flake8_print/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_pytest_style/mod.rs b/src/flake8_pytest_style/mod.rs index 6a643dee22..987f56b680 100644 --- a/src/flake8_pytest_style/mod.rs +++ b/src/flake8_pytest_style/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; pub mod types; diff --git a/src/flake8_pytest_style/rules/assertion.rs b/src/flake8_pytest_style/rules/assertion.rs index 0e1b8c92b1..79cc2e7a89 100644 --- a/src/flake8_pytest_style/rules/assertion.rs +++ b/src/flake8_pytest_style/rules/assertion.rs @@ -8,8 +8,8 @@ use crate::ast::helpers::unparse_stmt; use crate::ast::types::Range; use crate::ast::visitor; use crate::ast::visitor::Visitor; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/flake8_pytest_style/rules/fixture.rs b/src/flake8_pytest_style/rules/fixture.rs index 789aea3223..00f38ed7fe 100644 --- a/src/flake8_pytest_style/rules/fixture.rs +++ b/src/flake8_pytest_style/rules/fixture.rs @@ -8,8 +8,8 @@ use crate::ast::helpers::{collect_arg_names, collect_call_paths}; use crate::ast::types::Range; use crate::ast::visitor; use crate::ast::visitor::Visitor; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/flake8_pytest_style/rules/marks.rs b/src/flake8_pytest_style/rules/marks.rs index 6666c9472f..b91f45ba4a 100644 --- a/src/flake8_pytest_style/rules/marks.rs +++ b/src/flake8_pytest_style/rules/marks.rs @@ -2,8 +2,8 @@ use rustpython_ast::{Expr, ExprKind, Location}; use super::helpers::{get_mark_decorators, get_mark_name}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/flake8_pytest_style/rules/parametrize.rs b/src/flake8_pytest_style/rules/parametrize.rs index d2fc98b3f3..2a692ddfcf 100644 --- a/src/flake8_pytest_style/rules/parametrize.rs +++ b/src/flake8_pytest_style/rules/parametrize.rs @@ -3,11 +3,11 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind}; use super::helpers::is_pytest_parametrize; use crate::ast::helpers::create_expr; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::flake8_pytest_style::types; use crate::registry::{Diagnostic, RuleCode}; -use crate::source_code_generator::SourceCodeGenerator; +use crate::source_code::Generator; use crate::violations; fn get_parametrize_decorator<'a>(checker: &Checker, decorators: &'a [Expr]) -> Option<&'a Expr> { @@ -31,7 +31,7 @@ fn elts_to_csv(elts: &[Expr], checker: &Checker) -> Option { return None; } - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr( &create_expr(ExprKind::Constant { value: Constant::Str(elts.iter().fold(String::new(), |mut acc, elt| { @@ -85,7 +85,7 @@ fn check_names(checker: &mut Checker, expr: &Expr) { Range::from_located(expr), ); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr( &create_expr(ExprKind::Tuple { elts: names @@ -115,7 +115,7 @@ fn check_names(checker: &mut Checker, expr: &Expr) { Range::from_located(expr), ); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr( &create_expr(ExprKind::List { elts: names @@ -157,7 +157,7 @@ fn check_names(checker: &mut Checker, expr: &Expr) { Range::from_located(expr), ); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr( &create_expr(ExprKind::List { elts: elts.clone(), @@ -206,7 +206,7 @@ fn check_names(checker: &mut Checker, expr: &Expr) { Range::from_located(expr), ); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr( &create_expr(ExprKind::Tuple { elts: elts.clone(), @@ -284,7 +284,7 @@ fn handle_single_name(checker: &mut Checker, expr: &Expr, value: &Expr) { ); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr(&create_expr(value.node.clone()), 0); diagnostic.amend(Fix::replacement( generator.generate(), diff --git a/src/flake8_quotes/mod.rs b/src/flake8_quotes/mod.rs index 87d48b07f6..3d094ec87b 100644 --- a/src/flake8_quotes/mod.rs +++ b/src/flake8_quotes/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] @@ -8,10 +8,11 @@ mod tests { use anyhow::Result; use test_case::test_case; + use crate::flake8_quotes; use crate::flake8_quotes::settings::Quote; use crate::linter::test_path; use crate::registry::RuleCode; - use crate::{flake8_quotes, Settings}; + use crate::settings::Settings; #[test_case(Path::new("doubles.py"))] #[test_case(Path::new("doubles_escaped.py"))] diff --git a/src/flake8_quotes/rules.rs b/src/flake8_quotes/rules.rs index 6c89913734..c48dd9a31a 100644 --- a/src/flake8_quotes/rules.rs +++ b/src/flake8_quotes/rules.rs @@ -3,7 +3,7 @@ use rustpython_ast::Location; use crate::ast::types::Range; use crate::flake8_quotes::settings::{Quote, Settings}; use crate::registry::Diagnostic; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; fn good_single(quote: &Quote) -> char { @@ -42,7 +42,7 @@ fn good_docstring(quote: &Quote) -> &str { } pub fn quotes( - locator: &SourceCodeLocator, + locator: &Locator, start: Location, end: Location, is_docstring: bool, diff --git a/src/flake8_return/mod.rs b/src/flake8_return/mod.rs index 1273b8ccbd..6a4ac9086d 100644 --- a/src/flake8_return/mod.rs +++ b/src/flake8_return/mod.rs @@ -1,5 +1,5 @@ mod helpers; -pub mod rules; +pub(crate) mod rules; mod visitor; #[cfg(test)] @@ -11,7 +11,7 @@ mod tests { use crate::linter::test_path; use crate::registry::RuleCode; - use crate::Settings; + use crate::settings::Settings; #[test_case(RuleCode::RET501, Path::new("RET501.py"); "RET501")] #[test_case(RuleCode::RET502, Path::new("RET502.py"); "RET502")] diff --git a/src/flake8_return/rules.rs b/src/flake8_return/rules.rs index b17e546343..6e001ab805 100644 --- a/src/flake8_return/rules.rs +++ b/src/flake8_return/rules.rs @@ -4,13 +4,13 @@ use rustpython_ast::{Constant, Expr, ExprKind, Location, Stmt, StmtKind}; use crate::ast::types::Range; use crate::ast::visitor::Visitor; use crate::ast::whitespace::indentation; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::flake8_return::helpers::result_exists; use crate::flake8_return::visitor::{ReturnVisitor, Stack}; -use crate::registry::RuleCode; +use crate::registry::{Diagnostic, RuleCode}; +use crate::violations; use crate::violations::Branch; -use crate::{violations, Diagnostic}; /// RET501 fn unnecessary_return_none(checker: &mut Checker, stack: &Stack) { diff --git a/src/flake8_simplify/mod.rs b/src/flake8_simplify/mod.rs index b751e30d8f..f55914034a 100644 --- a/src/flake8_simplify/mod.rs +++ b/src/flake8_simplify/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/flake8_simplify/rules/ast_bool_op.rs b/src/flake8_simplify/rules/ast_bool_op.rs index 32bf51457a..b0422f7eff 100644 --- a/src/flake8_simplify/rules/ast_bool_op.rs +++ b/src/flake8_simplify/rules/ast_bool_op.rs @@ -7,8 +7,8 @@ use rustpython_ast::{Boolop, Cmpop, Constant, Expr, ExprContext, ExprKind, Unary use crate::ast::helpers::{create_expr, unparse_expr}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/flake8_simplify/rules/ast_expr.rs b/src/flake8_simplify/rules/ast_expr.rs index 0fa76d56ac..c305dfc2e7 100644 --- a/src/flake8_simplify/rules/ast_expr.rs +++ b/src/flake8_simplify/rules/ast_expr.rs @@ -2,8 +2,8 @@ use rustpython_ast::{Constant, Expr, ExprKind}; use crate::ast::helpers::{create_expr, match_module_member, unparse_expr}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/flake8_simplify/rules/ast_for.rs b/src/flake8_simplify/rules/ast_for.rs index 2c58057112..530ef9e5b6 100644 --- a/src/flake8_simplify/rules/ast_for.rs +++ b/src/flake8_simplify/rules/ast_for.rs @@ -4,11 +4,10 @@ use rustpython_ast::{ use crate::ast::helpers::{create_expr, create_stmt}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; -use crate::source_code_generator::SourceCodeGenerator; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::{Generator, Stylist}; use crate::violations; struct Loop<'a> { @@ -77,14 +76,8 @@ fn return_values<'a>(stmt: &'a Stmt, sibling: &'a Stmt) -> Option> { } /// Generate a return statement for an `any` or `all` builtin comprehension. -fn return_stmt( - id: &str, - test: &Expr, - target: &Expr, - iter: &Expr, - stylist: &SourceCodeStyleDetector, -) -> String { - let mut generator: SourceCodeGenerator = stylist.into(); +fn return_stmt(id: &str, test: &Expr, target: &Expr, iter: &Expr, stylist: &Stylist) -> String { + let mut generator: Generator = stylist.into(); generator.unparse_stmt(&create_stmt(StmtKind::Return { value: Some(Box::new(create_expr(ExprKind::Call { func: Box::new(create_expr(ExprKind::Name { diff --git a/src/flake8_simplify/rules/ast_if.rs b/src/flake8_simplify/rules/ast_if.rs index b9f134bed0..a183b6fba2 100644 --- a/src/flake8_simplify/rules/ast_if.rs +++ b/src/flake8_simplify/rules/ast_if.rs @@ -5,8 +5,8 @@ use crate::ast::helpers::{ contains_call_path, create_expr, create_stmt, has_comments, unparse_expr, unparse_stmt, }; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/flake8_simplify/rules/ast_ifexp.rs b/src/flake8_simplify/rules/ast_ifexp.rs index e1520c05b9..4f901274f7 100644 --- a/src/flake8_simplify/rules/ast_ifexp.rs +++ b/src/flake8_simplify/rules/ast_ifexp.rs @@ -2,8 +2,8 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Unaryop}; use crate::ast::helpers::{create_expr, unparse_expr}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/flake8_simplify/rules/ast_unary_op.rs b/src/flake8_simplify/rules/ast_unary_op.rs index 2126ef611f..44434d3140 100644 --- a/src/flake8_simplify/rules/ast_unary_op.rs +++ b/src/flake8_simplify/rules/ast_unary_op.rs @@ -2,8 +2,8 @@ use rustpython_ast::{Cmpop, Expr, ExprKind, Stmt, StmtKind, Unaryop}; use crate::ast::helpers::{create_expr, unparse_expr}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/flake8_simplify/rules/key_in_dict.rs b/src/flake8_simplify/rules/key_in_dict.rs index 6089458193..d8d21d438e 100644 --- a/src/flake8_simplify/rules/key_in_dict.rs +++ b/src/flake8_simplify/rules/key_in_dict.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Cmpop, Expr, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/flake8_simplify/rules/yoda_conditions.rs b/src/flake8_simplify/rules/yoda_conditions.rs index fe60b103b6..29cc571cbe 100644 --- a/src/flake8_simplify/rules/yoda_conditions.rs +++ b/src/flake8_simplify/rules/yoda_conditions.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Cmpop, Expr, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/flake8_tidy_imports/mod.rs b/src/flake8_tidy_imports/mod.rs index f8cc4037dc..19f391f27e 100644 --- a/src/flake8_tidy_imports/mod.rs +++ b/src/flake8_tidy_imports/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] @@ -8,10 +8,11 @@ mod tests { use anyhow::Result; use rustc_hash::FxHashMap; + use crate::flake8_tidy_imports; use crate::flake8_tidy_imports::settings::{BannedApi, Strictness}; use crate::linter::test_path; use crate::registry::RuleCode; - use crate::{flake8_tidy_imports, Settings}; + use crate::settings::Settings; #[test] fn ban_parent_imports() -> Result<()> { diff --git a/src/flake8_unused_arguments/mod.rs b/src/flake8_unused_arguments/mod.rs index 304216e6e7..0e12331fb1 100644 --- a/src/flake8_unused_arguments/mod.rs +++ b/src/flake8_unused_arguments/mod.rs @@ -1,5 +1,5 @@ mod helpers; -pub mod rules; +pub(crate) mod rules; pub mod settings; mod types; diff --git a/src/flake8_unused_arguments/rules.rs b/src/flake8_unused_arguments/rules.rs index 56c1bf33d2..df5183d130 100644 --- a/src/flake8_unused_arguments/rules.rs +++ b/src/flake8_unused_arguments/rules.rs @@ -10,7 +10,8 @@ use crate::ast::types::{Binding, BindingKind, FunctionDef, Lambda, Scope, ScopeK use crate::checkers::ast::Checker; use crate::flake8_unused_arguments::helpers; use crate::flake8_unused_arguments::types::Argumentable; -use crate::{visibility, Diagnostic}; +use crate::registry::Diagnostic; +use crate::visibility; /// Check a plain function for unused arguments. fn function( diff --git a/src/isort/comments.rs b/src/isort/comments.rs index 3dc39a69b3..f3277743fe 100644 --- a/src/isort/comments.rs +++ b/src/isort/comments.rs @@ -5,7 +5,7 @@ use rustpython_parser::lexer; use rustpython_parser::lexer::Tok; use crate::ast::types::Range; -use crate::SourceCodeLocator; +use crate::source_code::Locator; #[derive(Debug)] pub struct Comment<'a> { @@ -15,7 +15,7 @@ pub struct Comment<'a> { } /// Collect all comments in an import block. -pub fn collect_comments<'a>(range: &Range, locator: &'a SourceCodeLocator) -> Vec> { +pub fn collect_comments<'a>(range: &Range, locator: &'a Locator) -> Vec> { let contents = locator.slice_source_code_range(range); lexer::make_tokenizer_located(&contents, range.location) .flatten() diff --git a/src/isort/format.rs b/src/isort/format.rs index 80a15402ea..6d10c5a0bc 100644 --- a/src/isort/format.rs +++ b/src/isort/format.rs @@ -1,5 +1,5 @@ use crate::isort::types::{AliasData, CommentSet, ImportFromData, Importable}; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::Stylist; // Hard-code four-space indentation for the imports themselves, to match Black. const INDENT: &str = " "; @@ -12,7 +12,7 @@ pub fn format_import( alias: &AliasData, comments: &CommentSet, is_first: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> String { let mut output = String::with_capacity(CAPACITY); if !is_first && !comments.atop.is_empty() { @@ -46,7 +46,7 @@ pub fn format_import_from( comments: &CommentSet, aliases: &[(AliasData, CommentSet)], line_length: usize, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, force_wrap_aliases: bool, is_first: bool, trailing_comma: bool, @@ -89,7 +89,7 @@ fn format_single_line( comments: &CommentSet, aliases: &[(AliasData, CommentSet)], is_first: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> (String, usize) { let mut output = String::with_capacity(CAPACITY); let mut line_length = 0; @@ -149,7 +149,7 @@ fn format_multi_line( comments: &CommentSet, aliases: &[(AliasData, CommentSet)], is_first: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> String { let mut output = String::with_capacity(CAPACITY); diff --git a/src/isort/helpers.rs b/src/isort/helpers.rs index e7f651fb08..5829f38c48 100644 --- a/src/isort/helpers.rs +++ b/src/isort/helpers.rs @@ -5,11 +5,11 @@ use rustpython_parser::lexer::Tok; use crate::ast::helpers::is_docstring_stmt; use crate::ast::types::Range; use crate::isort::types::TrailingComma; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; /// Return `true` if a `StmtKind::ImportFrom` statement ends with a magic /// trailing comma. -pub fn trailing_comma(stmt: &Stmt, locator: &SourceCodeLocator) -> TrailingComma { +pub fn trailing_comma(stmt: &Stmt, locator: &Locator) -> TrailingComma { let contents = locator.slice_source_code_range(&Range::from_located(stmt)); let mut count: usize = 0; let mut trailing_comma = TrailingComma::Absent; @@ -37,7 +37,7 @@ pub fn trailing_comma(stmt: &Stmt, locator: &SourceCodeLocator) -> TrailingComma } /// Return `true` if a `Stmt` is preceded by a "comment break" -pub fn has_comment_break(stmt: &Stmt, locator: &SourceCodeLocator) -> bool { +pub fn has_comment_break(stmt: &Stmt, locator: &Locator) -> bool { // Starting from the `Stmt` (`def f(): pass`), we want to detect patterns like // this: // @@ -108,7 +108,7 @@ fn match_docstring_end(body: &[Stmt]) -> Option { /// Find the end of the first token that isn't a docstring, comment, or /// whitespace. -pub fn find_splice_location(body: &[Stmt], locator: &SourceCodeLocator) -> Location { +pub fn find_splice_location(body: &[Stmt], locator: &Locator) -> Location { // Find the first AST node that isn't a docstring. let mut splice = match_docstring_end(body).unwrap_or_default(); @@ -132,11 +132,11 @@ mod tests { use rustpython_parser::parser; use crate::isort::helpers::find_splice_location; - use crate::source_code_locator::SourceCodeLocator; + use crate::source_code::Locator; fn splice_contents(contents: &str) -> Result { let program = parser::parse_program(contents, "")?; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); Ok(find_splice_location(&program, &locator)) } diff --git a/src/isort/mod.rs b/src/isort/mod.rs index e3e6941618..f3c012225f 100644 --- a/src/isort/mod.rs +++ b/src/isort/mod.rs @@ -18,18 +18,17 @@ use crate::isort::types::{ AliasData, CommentSet, EitherImport, ImportBlock, ImportFromData, Importable, OrderedImportBlock, TrailingComma, }; -use crate::source_code_style::SourceCodeStyleDetector; -use crate::SourceCodeLocator; +use crate::source_code::{Locator, Stylist}; mod categorize; mod comments; -pub mod format; -pub mod helpers; -pub mod rules; +mod format; +mod helpers; +pub(crate) mod rules; pub mod settings; mod sorting; -pub mod track; -pub mod types; +pub(crate) mod track; +mod types; #[derive(Debug)] pub struct AnnotatedAliasData<'a> { @@ -59,7 +58,7 @@ pub enum AnnotatedImport<'a> { fn annotate_imports<'a>( imports: &'a [&'a Stmt], comments: Vec>, - locator: &SourceCodeLocator, + locator: &Locator, split_on_trailing_comma: bool, ) -> Vec> { let mut annotated = vec![]; @@ -536,9 +535,9 @@ fn force_single_line_imports<'a>( pub fn format_imports( block: &Block, comments: Vec, - locator: &SourceCodeLocator, + locator: &Locator, line_length: usize, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, src: &[PathBuf], package: Option<&Path>, known_first_party: &BTreeSet, @@ -647,9 +646,10 @@ mod tests { use anyhow::Result; use test_case::test_case; + use crate::isort; use crate::linter::test_path; use crate::registry::RuleCode; - use crate::{isort, Settings}; + use crate::settings::Settings; #[test_case(Path::new("add_newline_before_comments.py"))] #[test_case(Path::new("combine_as_imports.py"))] diff --git a/src/isort/rules/add_required_imports.rs b/src/isort/rules/add_required_imports.rs index 422367aff4..bfe175158d 100644 --- a/src/isort/rules/add_required_imports.rs +++ b/src/isort/rules/add_required_imports.rs @@ -5,12 +5,12 @@ use rustpython_ast::{Location, StmtKind, Suite}; use crate::ast::helpers::is_docstring_stmt; use crate::ast::types::Range; -use crate::autofix::Fix; +use crate::fix::Fix; use crate::isort::helpers; use crate::isort::track::Block; use crate::registry::{Diagnostic, RuleCode}; use crate::settings::{flags, Settings}; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; struct Alias<'a> { @@ -101,7 +101,7 @@ fn add_required_import( required_import: &AnyImport, blocks: &[&Block], python_ast: &Suite, - locator: &SourceCodeLocator, + locator: &Locator, settings: &Settings, autofix: flags::Autofix, ) -> Option { @@ -157,7 +157,7 @@ fn add_required_import( pub fn add_required_imports( blocks: &[&Block], python_ast: &Suite, - locator: &SourceCodeLocator, + locator: &Locator, settings: &Settings, autofix: flags::Autofix, ) -> Vec { diff --git a/src/isort/rules/organize_imports.rs b/src/isort/rules/organize_imports.rs index ae0335c2e2..eec33b41a7 100644 --- a/src/isort/rules/organize_imports.rs +++ b/src/isort/rules/organize_imports.rs @@ -8,12 +8,13 @@ use crate::ast::helpers::{ }; use crate::ast::types::Range; use crate::ast::whitespace::leading_space; -use crate::autofix::Fix; +use crate::fix::Fix; use crate::isort::track::Block; use crate::isort::{comments, format_imports}; -use crate::settings::flags; -use crate::source_code_style::SourceCodeStyleDetector; -use crate::{violations, Diagnostic, Settings, SourceCodeLocator}; +use crate::registry::Diagnostic; +use crate::settings::{flags, Settings}; +use crate::source_code::{Locator, Stylist}; +use crate::violations; fn extract_range(body: &[&Stmt]) -> Range { let location = body.first().unwrap().location; @@ -29,9 +30,9 @@ fn extract_indentation_range(body: &[&Stmt]) -> Range { /// I001 pub fn organize_imports( block: &Block, - locator: &SourceCodeLocator, + locator: &Locator, settings: &Settings, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, autofix: flags::Autofix, package: Option<&Path>, ) -> Option { diff --git a/src/isort/track.rs b/src/isort/track.rs index d75cbe957b..daf4fe0fac 100644 --- a/src/isort/track.rs +++ b/src/isort/track.rs @@ -9,7 +9,7 @@ use rustpython_ast::{ use crate::ast::visitor::Visitor; use crate::directives::IsortDirectives; use crate::isort::helpers; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; #[derive(Debug)] pub enum Trailer { @@ -26,7 +26,7 @@ pub struct Block<'a> { } pub struct ImportTracker<'a> { - locator: &'a SourceCodeLocator<'a>, + locator: &'a Locator<'a>, directives: &'a IsortDirectives, pyi: bool, blocks: Vec>, @@ -35,11 +35,7 @@ pub struct ImportTracker<'a> { } impl<'a> ImportTracker<'a> { - pub fn new( - locator: &'a SourceCodeLocator<'a>, - directives: &'a IsortDirectives, - path: &'a Path, - ) -> Self { + pub fn new(locator: &'a Locator<'a>, directives: &'a IsortDirectives, path: &'a Path) -> Self { Self { locator, directives, diff --git a/src/lib.rs b/src/lib.rs index a6bdc5abf4..5bb7dfb2f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,21 +12,17 @@ )] #![forbid(unsafe_code)] -use cfg_if::cfg_if; - -use crate::registry::Diagnostic; -use crate::settings::Settings; -use crate::source_code_locator::SourceCodeLocator; - mod ast; -pub mod autofix; -pub mod cache; +mod autofix; +mod cache; mod checkers; pub mod cli; mod cst; mod directives; +mod doc_lines; mod docstrings; mod eradicate; +pub mod fix; mod flake8_2020; pub mod flake8_annotations; pub mod flake8_bandit; @@ -40,6 +36,7 @@ mod flake8_debugger; pub mod flake8_errmsg; mod flake8_implicit_str_concat; mod flake8_import_conventions; +pub mod flake8_pie; mod flake8_print; pub mod flake8_pytest_style; pub mod flake8_quotes; @@ -71,18 +68,19 @@ pub mod resolver; mod ruff; mod rustpython_helpers; pub mod settings; -pub mod source_code_generator; -pub mod source_code_locator; -pub mod source_code_style; +pub mod source_code; mod vendor; mod violation; mod violations; -pub mod visibility; +mod visibility; + +use cfg_if::cfg_if; cfg_if! { if #[cfg(not(target_family = "wasm"))] { pub mod commands; - mod packages; + mod packaging; + #[cfg(all(feature = "update-informer"))] pub mod updates; @@ -93,5 +91,3 @@ cfg_if! { pub use lib_wasm::check; } } -pub mod doc_lines; -pub mod flake8_pie; diff --git a/src/lib_native.rs b/src/lib_native.rs index f1adbd0c73..2863464e55 100644 --- a/src/lib_native.rs +++ b/src/lib_native.rs @@ -10,9 +10,8 @@ use crate::resolver::Relativity; use crate::rustpython_helpers::tokenize; use crate::settings::configuration::Configuration; use crate::settings::{flags, pyproject, Settings}; -use crate::source_code_locator::SourceCodeLocator; -use crate::source_code_style::SourceCodeStyleDetector; -use crate::{directives, packages, resolver}; +use crate::source_code::{Locator, Stylist}; +use crate::{directives, packaging, resolver}; /// Load the relevant `Settings` for a given `Path`. fn resolve(path: &Path) -> Result { @@ -40,10 +39,10 @@ pub fn check(path: &Path, contents: &str, autofix: bool) -> Result = tokenize(contents); // Map row and column locations to byte slices (lazily). - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); // Detect the current code style (lazily). - let stylist = SourceCodeStyleDetector::from_contents(contents, &locator); + let stylist = Stylist::from_contents(contents, &locator); // Extract the `# noqa` and `# isort: skip` directives from the source. let directives = @@ -52,7 +51,7 @@ pub fn check(path: &Path, contents: &str, autofix: bool) -> Result Result { let tokens: Vec = tokenize(contents); // Map row and column locations to byte slices (lazily). - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); // Detect the current code style (lazily). - let stylist = SourceCodeStyleDetector::from_contents(contents, &locator); + let stylist = Stylist::from_contents(contents, &locator); // Extract the `# noqa` and `# isort: skip` directives from the source. let directives = directives::extract_directives(&tokens, directives::Flags::empty()); diff --git a/src/linter.rs b/src/linter.rs index 1697741d46..29478eafed 100644 --- a/src/linter.rs +++ b/src/linter.rs @@ -11,8 +11,7 @@ use rustpython_parser::lexer::LexResult; use similar::TextDiff; use crate::ast::types::Range; -use crate::autofix::fixer; -use crate::autofix::fixer::fix_file; +use crate::autofix::fix_file; use crate::checkers::ast::check_ast; use crate::checkers::imports::check_imports; use crate::checkers::lines::check_lines; @@ -24,9 +23,8 @@ use crate::message::{Message, Source}; use crate::noqa::add_noqa; use crate::registry::{Diagnostic, LintSource, RuleCode}; use crate::settings::{flags, Settings}; -use crate::source_code_locator::SourceCodeLocator; -use crate::source_code_style::SourceCodeStyleDetector; -use crate::{cache, directives, fs, rustpython_helpers, violations}; +use crate::source_code::{Locator, Stylist}; +use crate::{cache, directives, fix, fs, rustpython_helpers, violations}; const CARGO_PKG_NAME: &str = env!("CARGO_PKG_NAME"); const CARGO_PKG_REPOSITORY: &str = env!("CARGO_PKG_REPOSITORY"); @@ -58,8 +56,8 @@ pub(crate) fn check_path( package: Option<&Path>, contents: &str, tokens: Vec, - locator: &SourceCodeLocator, - stylist: &SourceCodeStyleDetector, + locator: &Locator, + stylist: &Stylist, directives: &Directives, settings: &Settings, autofix: flags::Autofix, @@ -200,7 +198,7 @@ pub fn lint_path( package: Option<&Path>, settings: &Settings, cache: flags::Cache, - autofix: fixer::Mode, + autofix: fix::FixMode, ) -> Result { // Validate the `Settings` and return any errors. settings.validate()?; @@ -212,7 +210,7 @@ pub fn lint_path( // write the fixes to disk, thus invalidating the cache. But it's a bit hard // to reason about. We need to come up with a better solution here.) let metadata = if matches!(cache, flags::Cache::Enabled) - && matches!(autofix, fixer::Mode::None | fixer::Mode::Generate) + && matches!(autofix, fix::FixMode::None | fix::FixMode::Generate) { let metadata = path.metadata()?; if let Some(messages) = cache::get(path, &metadata, settings, autofix.into()) { @@ -228,12 +226,12 @@ pub fn lint_path( let contents = fs::read_file(path)?; // Lint the file. - let (messages, fixed) = if matches!(autofix, fixer::Mode::Apply | fixer::Mode::Diff) { + let (messages, fixed) = if matches!(autofix, fix::FixMode::Apply | fix::FixMode::Diff) { let (transformed, fixed, messages) = lint_fix(&contents, path, package, settings)?; if fixed > 0 { - if matches!(autofix, fixer::Mode::Apply) { + if matches!(autofix, fix::FixMode::Apply) { write(path, transformed)?; - } else if matches!(autofix, fixer::Mode::Diff) { + } else if matches!(autofix, fix::FixMode::Diff) { let mut stdout = io::stdout().lock(); TextDiff::from_lines(&contents, &transformed) .unified_diff() @@ -270,10 +268,10 @@ pub fn add_noqa_to_path(path: &Path, settings: &Settings) -> Result { let tokens: Vec = rustpython_helpers::tokenize(&contents); // Map row and column locations to byte slices (lazily). - let locator = SourceCodeLocator::new(&contents); + let locator = Locator::new(&contents); // Detect the current code style (lazily). - let stylist = SourceCodeStyleDetector::from_contents(&contents, &locator); + let stylist = Stylist::from_contents(&contents, &locator); // Extract the `# noqa` and `# isort: skip` directives from the source. let directives = @@ -310,13 +308,13 @@ pub fn lint_stdin( package: Option<&Path>, contents: &str, settings: &Settings, - autofix: fixer::Mode, + autofix: fix::FixMode, ) -> Result { // Validate the `Settings` and return any errors. settings.validate()?; // Lint the inputs. - let (messages, fixed) = if matches!(autofix, fixer::Mode::Apply | fixer::Mode::Diff) { + let (messages, fixed) = if matches!(autofix, fix::FixMode::Apply | fix::FixMode::Diff) { let (transformed, fixed, messages) = lint_fix( contents, path.unwrap_or_else(|| Path::new("-")), @@ -324,10 +322,10 @@ pub fn lint_stdin( settings, )?; - if matches!(autofix, fixer::Mode::Apply) { + if matches!(autofix, fix::FixMode::Apply) { // Write the contents to stdout, regardless of whether any errors were fixed. io::stdout().write_all(transformed.as_bytes())?; - } else if matches!(autofix, fixer::Mode::Diff) { + } else if matches!(autofix, fix::FixMode::Diff) { // But only write a diff if it's non-empty. if fixed > 0 { let text_diff = TextDiff::from_lines(contents, &transformed); @@ -372,10 +370,10 @@ fn lint_only( let tokens: Vec = rustpython_helpers::tokenize(contents); // Map row and column locations to byte slices (lazily). - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); // Detect the current code style (lazily). - let stylist = SourceCodeStyleDetector::from_contents(contents, &locator); + let stylist = Stylist::from_contents(contents, &locator); // Extract the `# noqa` and `# isort: skip` directives from the source. let directives = @@ -432,10 +430,10 @@ fn lint_fix( let tokens: Vec = rustpython_helpers::tokenize(&contents); // Map row and column locations to byte slices (lazily). - let locator = SourceCodeLocator::new(&contents); + let locator = Locator::new(&contents); // Detect the current code style (lazily). - let stylist = SourceCodeStyleDetector::from_contents(&contents, &locator); + let stylist = Stylist::from_contents(&contents, &locator); // Extract the `# noqa` and `# isort: skip` directives from the source. let directives = @@ -511,8 +509,8 @@ quoting the contents of `{}`, along with the `pyproject.toml` settings and execu pub fn test_path(path: &Path, settings: &Settings) -> Result> { let contents = fs::read_file(path)?; let tokens: Vec = rustpython_helpers::tokenize(&contents); - let locator = SourceCodeLocator::new(&contents); - let stylist = SourceCodeStyleDetector::from_contents(&contents, &locator); + let locator = Locator::new(&contents); + let stylist = Stylist::from_contents(&contents, &locator); let directives = directives::extract_directives(&tokens, directives::Flags::from_settings(settings)); let mut diagnostics = check_path( @@ -540,8 +538,8 @@ pub fn test_path(path: &Path, settings: &Settings) -> Result> { loop { let tokens: Vec = rustpython_helpers::tokenize(&contents); - let locator = SourceCodeLocator::new(&contents); - let stylist = SourceCodeStyleDetector::from_contents(&contents, &locator); + let locator = Locator::new(&contents); + let stylist = Stylist::from_contents(&contents, &locator); let directives = directives::extract_directives(&tokens, directives::Flags::from_settings(settings)); let diagnostics = check_path( diff --git a/src/main_native.rs b/src/main_native.rs index a9f2745a6f..60aad35bbb 100644 --- a/src/main_native.rs +++ b/src/main_native.rs @@ -3,7 +3,6 @@ use std::path::{Path, PathBuf}; use std::process::ExitCode; use std::sync::mpsc::channel; -use ::ruff::autofix::fixer; use ::ruff::cli::{extract_log_level, Cli, Overrides}; use ::ruff::logging::{set_up_logging, LogLevel}; use ::ruff::printer::{Printer, Violations}; @@ -13,7 +12,7 @@ use ::ruff::settings::types::SerializationFormat; use ::ruff::settings::{pyproject, Settings}; #[cfg(feature = "update-informer")] use ::ruff::updates; -use ::ruff::{commands, warn_user_once}; +use ::ruff::{commands, fix, warn_user_once}; use anyhow::Result; use clap::{CommandFactory, Parser}; use colored::Colorize; @@ -152,13 +151,13 @@ pub(crate) fn inner_main() -> Result { // but not apply fixes. That would allow us to avoid special-casing JSON // here. let autofix = if cli.diff { - fixer::Mode::Diff + fix::FixMode::Diff } else if fix || fix_only { - fixer::Mode::Apply + fix::FixMode::Apply } else if matches!(format, SerializationFormat::Json) { - fixer::Mode::Generate + fix::FixMode::Generate } else { - fixer::Mode::None + fix::FixMode::None }; let violations = if cli.diff || fix_only { Violations::Hide @@ -176,7 +175,7 @@ pub(crate) fn inner_main() -> Result { let printer = Printer::new(&format, &log_level, &autofix, &violations); if cli.watch { - if !matches!(autofix, fixer::Mode::None) { + if !matches!(autofix, fix::FixMode::None) { warn_user_once!("--fix is not enabled in watch mode."); } if format != SerializationFormat::Text { @@ -193,7 +192,7 @@ pub(crate) fn inner_main() -> Result { &file_strategy, &overrides, cache.into(), - fixer::Mode::None, + fix::FixMode::None, )?; printer.write_continuously(&messages)?; @@ -223,7 +222,7 @@ pub(crate) fn inner_main() -> Result { &file_strategy, &overrides, cache.into(), - fixer::Mode::None, + fix::FixMode::None, )?; printer.write_continuously(&messages)?; } @@ -263,7 +262,7 @@ pub(crate) fn inner_main() -> Result { // Always try to print violations (the printer itself may suppress output), // unless we're writing fixes via stdin (in which case, the transformed // source code goes to stdout). - if !(is_stdin && matches!(autofix, fixer::Mode::Apply | fixer::Mode::Diff)) { + if !(is_stdin && matches!(autofix, fix::FixMode::Apply | fix::FixMode::Diff)) { printer.write_once(&diagnostics)?; } diff --git a/src/mccabe/mod.rs b/src/mccabe/mod.rs index 0174182eb1..d0b1de08e0 100644 --- a/src/mccabe/mod.rs +++ b/src/mccabe/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] @@ -9,8 +9,9 @@ mod tests { use test_case::test_case; use crate::linter::test_path; + use crate::mccabe; use crate::registry::RuleCode; - use crate::{mccabe, Settings}; + use crate::settings::Settings; #[test_case(0)] #[test_case(3)] diff --git a/src/mccabe/rules.rs b/src/mccabe/rules.rs index a42f30c78e..09ed45594e 100644 --- a/src/mccabe/rules.rs +++ b/src/mccabe/rules.rs @@ -2,7 +2,7 @@ use rustpython_ast::{ExcepthandlerKind, ExprKind, Stmt, StmtKind}; use crate::ast::helpers::identifier_range; use crate::registry::Diagnostic; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; fn get_complexity_number(stmts: &[Stmt]) -> usize { @@ -61,7 +61,7 @@ pub fn function_is_too_complex( name: &str, body: &[Stmt], max_complexity: usize, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { let complexity = get_complexity_number(body) + 1; if complexity > max_complexity { diff --git a/src/message.rs b/src/message.rs index 565ec2e8b6..e5b81b92ed 100644 --- a/src/message.rs +++ b/src/message.rs @@ -4,9 +4,9 @@ use rustpython_parser::ast::Location; use serde::{Deserialize, Serialize}; use crate::ast::types::Range; -use crate::autofix::Fix; +use crate::fix::Fix; use crate::registry::{Diagnostic, DiagnosticKind}; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Message { @@ -61,7 +61,7 @@ pub struct Source { } impl Source { - pub fn from_diagnostic(diagnostic: &Diagnostic, locator: &SourceCodeLocator) -> Self { + pub fn from_diagnostic(diagnostic: &Diagnostic, locator: &Locator) -> Self { let location = Location::new(diagnostic.location.row(), 0); // Diagnostics can already extend one-past-the-end per Ropey's semantics. If // they do, though, then they'll end at the start of a line. We need to diff --git a/src/noqa.rs b/src/noqa.rs index 4581640df5..0143b00ca0 100644 --- a/src/noqa.rs +++ b/src/noqa.rs @@ -9,7 +9,7 @@ use regex::Regex; use rustc_hash::{FxHashMap, FxHashSet}; use crate::registry::{Diagnostic, RuleCode, CODE_REDIRECTS}; -use crate::source_code_style::LineEnding; +use crate::source_code::LineEnding; static NOQA_LINE_REGEX: Lazy = Lazy::new(|| { Regex::new( @@ -207,7 +207,6 @@ fn add_noqa_inner( #[cfg(test)] mod tests { - use nohash_hasher::IntMap; use rustc_hash::FxHashSet; use rustpython_parser::ast::Location; @@ -215,7 +214,7 @@ mod tests { use crate::ast::types::Range; use crate::noqa::{add_noqa_inner, NOQA_LINE_REGEX}; use crate::registry::Diagnostic; - use crate::source_code_style::LineEnding; + use crate::source_code::LineEnding; use crate::violations; #[test] diff --git a/src/packages.rs b/src/packaging.rs similarity index 99% rename from src/packages.rs rename to src/packaging.rs index 86ad3e5bb8..0cef592c4c 100644 --- a/src/packages.rs +++ b/src/packaging.rs @@ -102,7 +102,7 @@ pub fn detect_package_roots<'a>(files: &[&'a Path]) -> FxHashMap<&'a Path, Optio mod tests { use std::path::PathBuf; - use crate::packages::detect_package_root; + use crate::packaging::detect_package_root; #[test] fn package_detection() { diff --git a/src/pandas_vet/mod.rs b/src/pandas_vet/mod.rs index eef329d7a8..e973026b9e 100644 --- a/src/pandas_vet/mod.rs +++ b/src/pandas_vet/mod.rs @@ -1,5 +1,5 @@ -pub mod helpers; -pub mod rules; +pub(crate) mod helpers; +pub(crate) mod rules; #[cfg(test)] mod tests { @@ -13,16 +13,15 @@ mod tests { use crate::linter::check_path; use crate::registry::{RuleCode, RuleCodePrefix}; use crate::settings::flags; - use crate::source_code_locator::SourceCodeLocator; - use crate::source_code_style::SourceCodeStyleDetector; + use crate::source_code::{Locator, Stylist}; use crate::{directives, rustpython_helpers, settings}; fn rule_code(contents: &str, expected: &[RuleCode]) -> Result<()> { let contents = dedent(contents); let settings = settings::Settings::for_rules(RuleCodePrefix::PD.codes()); let tokens: Vec = rustpython_helpers::tokenize(&contents); - let locator = SourceCodeLocator::new(&contents); - let stylist = SourceCodeStyleDetector::from_contents(&contents, &locator); + let locator = Locator::new(&contents); + let stylist = Stylist::from_contents(&contents, &locator); let directives = directives::extract_directives(&tokens, directives::Flags::from_settings(&settings)); let diagnostics = check_path( diff --git a/src/pep8_naming/mod.rs b/src/pep8_naming/mod.rs index 27b6036531..5bb1d62125 100644 --- a/src/pep8_naming/mod.rs +++ b/src/pep8_naming/mod.rs @@ -1,5 +1,5 @@ mod helpers; -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] diff --git a/src/pep8_naming/rules.rs b/src/pep8_naming/rules.rs index 0c34d516b1..dafa4bd54a 100644 --- a/src/pep8_naming/rules.rs +++ b/src/pep8_naming/rules.rs @@ -9,15 +9,11 @@ use crate::pep8_naming::helpers; use crate::pep8_naming::settings::Settings; use crate::python::string::{self}; use crate::registry::Diagnostic; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; /// N801 -pub fn invalid_class_name( - class_def: &Stmt, - name: &str, - locator: &SourceCodeLocator, -) -> Option { +pub fn invalid_class_name(class_def: &Stmt, name: &str, locator: &Locator) -> Option { let stripped = name.strip_prefix('_').unwrap_or(name); if !stripped.chars().next().map_or(false, char::is_uppercase) || stripped.contains('_') { return Some(Diagnostic::new( @@ -33,7 +29,7 @@ pub fn invalid_function_name( func_def: &Stmt, name: &str, ignore_names: &[String], - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if name.to_lowercase() != name && !ignore_names.iter().any(|ignore_name| ignore_name == name) { return Some(Diagnostic::new( @@ -153,7 +149,7 @@ pub fn dunder_function_name( scope: &Scope, stmt: &Stmt, name: &str, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if matches!(scope.kind, ScopeKind::Class(_)) { return None; @@ -177,7 +173,7 @@ pub fn constant_imported_as_non_constant( import_from: &Stmt, name: &str, asname: &str, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if string::is_upper(name) && !string::is_upper(asname) { return Some(Diagnostic::new( @@ -193,7 +189,7 @@ pub fn lowercase_imported_as_non_lowercase( import_from: &Stmt, name: &str, asname: &str, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if !string::is_upper(name) && string::is_lower(name) && asname.to_lowercase() != asname { return Some(Diagnostic::new( @@ -209,7 +205,7 @@ pub fn camelcase_imported_as_lowercase( import_from: &Stmt, name: &str, asname: &str, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if helpers::is_camelcase(name) && string::is_lower(asname) { return Some(Diagnostic::new( @@ -225,7 +221,7 @@ pub fn camelcase_imported_as_constant( import_from: &Stmt, name: &str, asname: &str, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if helpers::is_camelcase(name) && !string::is_lower(asname) @@ -279,7 +275,7 @@ pub fn camelcase_imported_as_acronym( import_from: &Stmt, name: &str, asname: &str, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if helpers::is_camelcase(name) && !string::is_lower(asname) @@ -299,7 +295,7 @@ pub fn error_suffix_on_exception_name( class_def: &Stmt, bases: &[Expr], name: &str, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if !bases.iter().any(|base| { if let ExprKind::Name { id, .. } = &base.node { diff --git a/src/printer.rs b/src/printer.rs index 3ce34b2e3d..a3455ff72c 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -10,14 +10,13 @@ use rustpython_parser::ast::Location; use serde::Serialize; use serde_json::json; -use crate::autofix::fixer; use crate::fs::relativize_path; use crate::linter::Diagnostics; use crate::logging::LogLevel; use crate::message::Message; -use crate::notify_user; use crate::registry::RuleCode; use crate::settings::types::SerializationFormat; +use crate::{fix, notify_user}; /// Enum to control whether lint violations are shown to the user. pub enum Violations { @@ -46,7 +45,7 @@ struct ExpandedMessage<'a> { pub struct Printer<'a> { format: &'a SerializationFormat, log_level: &'a LogLevel, - autofix: &'a fixer::Mode, + autofix: &'a fix::FixMode, violations: &'a Violations, } @@ -54,7 +53,7 @@ impl<'a> Printer<'a> { pub fn new( format: &'a SerializationFormat, log_level: &'a LogLevel, - autofix: &'a fixer::Mode, + autofix: &'a fix::FixMode, violations: &'a Violations, ) -> Self { Self { @@ -84,7 +83,7 @@ impl<'a> Printer<'a> { println!("Found {remaining} error(s)."); } - if !matches!(self.autofix, fixer::Mode::Apply) { + if !matches!(self.autofix, fix::FixMode::Apply) { let num_fixable = diagnostics .messages .iter() @@ -98,9 +97,9 @@ impl<'a> Printer<'a> { Violations::Hide => { let fixed = diagnostics.fixed; if fixed > 0 { - if matches!(self.autofix, fixer::Mode::Apply) { + if matches!(self.autofix, fix::FixMode::Apply) { println!("Fixed {fixed} error(s)."); - } else if matches!(self.autofix, fixer::Mode::Diff) { + } else if matches!(self.autofix, fix::FixMode::Diff) { println!("Would fix {fixed} error(s)."); } } diff --git a/src/pycodestyle/mod.rs b/src/pycodestyle/mod.rs index 1c78298742..f8e99b596d 100644 --- a/src/pycodestyle/mod.rs +++ b/src/pycodestyle/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; pub mod settings; #[cfg(test)] diff --git a/src/pycodestyle/rules.rs b/src/pycodestyle/rules.rs index 2aec73fd98..3d81aa3e34 100644 --- a/src/pycodestyle/rules.rs +++ b/src/pycodestyle/rules.rs @@ -11,13 +11,11 @@ use crate::ast::helpers::{ }; use crate::ast::types::Range; use crate::ast::whitespace::leading_space; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::settings::Settings; -use crate::source_code_generator::SourceCodeGenerator; -use crate::source_code_locator::SourceCodeLocator; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::{Generator, Locator, Stylist}; use crate::violations; static URL_REGEX: Lazy = Lazy::new(|| Regex::new(r"^https?://\S+$").unwrap()); @@ -106,12 +104,7 @@ pub fn doc_line_too_long(lineno: usize, line: &str, settings: &Settings) -> Opti } } -fn compare( - left: &Expr, - ops: &[Cmpop], - comparators: &[Expr], - stylist: &SourceCodeStyleDetector, -) -> String { +fn compare(left: &Expr, ops: &[Cmpop], comparators: &[Expr], stylist: &Stylist) -> String { unparse_expr( &create_expr(ExprKind::Compare { left: Box::new(left.clone()), @@ -413,7 +406,7 @@ pub fn do_not_use_bare_except( type_: Option<&Expr>, body: &[Stmt], handler: &Excepthandler, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { if type_.is_none() && !body @@ -429,12 +422,7 @@ pub fn do_not_use_bare_except( } } -fn function( - name: &str, - args: &Arguments, - body: &Expr, - stylist: &SourceCodeStyleDetector, -) -> String { +fn function(name: &str, args: &Arguments, body: &Expr, stylist: &Stylist) -> String { let body = Stmt::new( Location::default(), Location::default(), @@ -454,7 +442,7 @@ fn function( type_comment: None, }, ); - let mut generator: SourceCodeGenerator = stylist.into(); + let mut generator: Generator = stylist.into(); generator.unparse_stmt(&func); generator.generate() } @@ -585,7 +573,7 @@ fn extract_quote(text: &str) -> &str { /// W605 pub fn invalid_escape_sequence( - locator: &SourceCodeLocator, + locator: &Locator, start: Location, end: Location, autofix: bool, diff --git a/src/pydocstyle/mod.rs b/src/pydocstyle/mod.rs index ea5f61888e..85d004193c 100644 --- a/src/pydocstyle/mod.rs +++ b/src/pydocstyle/mod.rs @@ -1,5 +1,5 @@ -pub mod helpers; -pub mod rules; +pub(crate) mod helpers; +pub(crate) mod rules; pub mod settings; #[cfg(test)] diff --git a/src/pydocstyle/rules.rs b/src/pydocstyle/rules.rs index d75d3093f7..df57f75abf 100644 --- a/src/pydocstyle/rules.rs +++ b/src/pydocstyle/rules.rs @@ -8,12 +8,12 @@ use crate::ast::helpers::identifier_range; use crate::ast::types::Range; use crate::ast::whitespace::LinesWithTrailingNewline; use crate::ast::{cast, whitespace}; -use crate::autofix::Fix; use crate::checkers::ast::Checker; use crate::docstrings::constants; use crate::docstrings::definition::{Definition, DefinitionKind, Docstring}; use crate::docstrings::sections::{section_contexts, SectionContext}; use crate::docstrings::styles::SectionStyle; +use crate::fix::Fix; use crate::pydocstyle::helpers::{leading_quote, logical_line}; use crate::pydocstyle::settings::Convention; use crate::registry::{Diagnostic, RuleCode}; diff --git a/src/pyflakes/fixes.rs b/src/pyflakes/fixes.rs index 2b4f3c1418..0362ef3c0d 100644 --- a/src/pyflakes/fixes.rs +++ b/src/pyflakes/fixes.rs @@ -5,16 +5,16 @@ use rustpython_parser::lexer; use rustpython_parser::lexer::Tok; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::cst::matchers::{match_expr, match_module}; +use crate::fix::Fix; use crate::python::string::strip_quotes_and_prefixes; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; /// Generate a `Fix` to remove unused keys from format dict. pub fn remove_unused_format_arguments_from_dict( unused_arguments: &[&str], stmt: &Expr, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(stmt)); let mut tree = match_module(&module_text)?; @@ -60,7 +60,7 @@ pub fn remove_unused_format_arguments_from_dict( pub fn remove_unused_keyword_arguments_from_format_call( unused_arguments: &[&str], location: Range, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Result { let module_text = locator.slice_source_code_range(&location); let mut tree = match_module(&module_text)?; @@ -103,7 +103,7 @@ pub fn remove_unused_keyword_arguments_from_format_call( /// Generate a `Fix` to remove the binding from an exception handler. pub fn remove_exception_handler_assignment( excepthandler: &Excepthandler, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Result { let contents = locator.slice_source_code_range(&Range::from_located(excepthandler)); let mut fix_start = None; diff --git a/src/pyflakes/mod.rs b/src/pyflakes/mod.rs index 290ef25e79..a0dbd912f1 100644 --- a/src/pyflakes/mod.rs +++ b/src/pyflakes/mod.rs @@ -1,7 +1,7 @@ -pub mod cformat; -pub mod fixes; -pub mod format; -pub mod rules; +pub(crate) mod cformat; +pub(crate) mod fixes; +pub(crate) mod format; +pub(crate) mod rules; #[cfg(test)] mod tests { @@ -17,8 +17,7 @@ mod tests { use crate::linter::{check_path, test_path}; use crate::registry::{RuleCode, RuleCodePrefix}; use crate::settings::flags; - use crate::source_code_locator::SourceCodeLocator; - use crate::source_code_style::SourceCodeStyleDetector; + use crate::source_code::{Locator, Stylist}; use crate::{directives, rustpython_helpers, settings}; #[test_case(RuleCode::F401, Path::new("F401_0.py"); "F401_0")] @@ -212,8 +211,8 @@ mod tests { let contents = dedent(contents); let settings = settings::Settings::for_rules(RuleCodePrefix::F.codes()); let tokens: Vec = rustpython_helpers::tokenize(&contents); - let locator = SourceCodeLocator::new(&contents); - let stylist = SourceCodeStyleDetector::from_contents(&contents, &locator); + let locator = Locator::new(&contents); + let stylist = Stylist::from_contents(&contents, &locator); let directives = directives::extract_directives(&tokens, directives::Flags::from_settings(&settings)); let mut diagnostics = check_path( diff --git a/src/pyflakes/rules/f_string_missing_placeholders.rs b/src/pyflakes/rules/f_string_missing_placeholders.rs index a64e4ae9a7..fc7cff0e3d 100644 --- a/src/pyflakes/rules/f_string_missing_placeholders.rs +++ b/src/pyflakes/rules/f_string_missing_placeholders.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Expr, ExprKind}; use crate::ast::helpers::find_useless_f_strings; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/pyflakes/rules/invalid_literal_comparisons.rs b/src/pyflakes/rules/invalid_literal_comparisons.rs index 488592d9aa..d77be3f153 100644 --- a/src/pyflakes/rules/invalid_literal_comparisons.rs +++ b/src/pyflakes/rules/invalid_literal_comparisons.rs @@ -5,8 +5,8 @@ use rustpython_ast::{Cmpop, Expr}; use crate::ast::helpers; use crate::ast::operations::locate_cmpops; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyflakes/rules/mod.rs b/src/pyflakes/rules/mod.rs index 37d8493492..510a9bc67f 100644 --- a/src/pyflakes/rules/mod.rs +++ b/src/pyflakes/rules/mod.rs @@ -34,7 +34,7 @@ use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, S use crate::ast::helpers::except_range; use crate::ast::types::{Binding, Range, Scope, ScopeKind}; use crate::registry::Diagnostic; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; /// F821 @@ -62,7 +62,7 @@ pub fn undefined_local(name: &str, scopes: &[&Scope], bindings: &[Binding]) -> O /// F707 pub fn default_except_not_last( handlers: &[Excepthandler], - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { for (idx, handler) in handlers.iter().enumerate() { let ExcepthandlerKind::ExceptHandler { type_, .. } = &handler.node; diff --git a/src/pyflakes/rules/raise_not_implemented.rs b/src/pyflakes/rules/raise_not_implemented.rs index 0876be4e00..405a425779 100644 --- a/src/pyflakes/rules/raise_not_implemented.rs +++ b/src/pyflakes/rules/raise_not_implemented.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Expr, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyflakes/rules/repeated_keys.rs b/src/pyflakes/rules/repeated_keys.rs index 816713d21f..1570370e98 100644 --- a/src/pyflakes/rules/repeated_keys.rs +++ b/src/pyflakes/rules/repeated_keys.rs @@ -6,8 +6,8 @@ use rustpython_ast::{Expr, ExprKind}; use crate::ast::comparable::{ComparableConstant, ComparableExpr}; use crate::ast::helpers::unparse_expr; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/pyflakes/rules/unused_variable.rs b/src/pyflakes/rules/unused_variable.rs index 14220633d6..2e8c21244c 100644 --- a/src/pyflakes/rules/unused_variable.rs +++ b/src/pyflakes/rules/unused_variable.rs @@ -3,8 +3,8 @@ use rustpython_ast::{Expr, ExprKind, Stmt, StmtKind}; use crate::ast::types::{BindingKind, Range, RefEquality, ScopeKind}; use crate::autofix::helpers::delete_stmt; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/pygrep_hooks/mod.rs b/src/pygrep_hooks/mod.rs index 82f5427fb2..ffa6b32d1e 100644 --- a/src/pygrep_hooks/mod.rs +++ b/src/pygrep_hooks/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/pylint/mod.rs b/src/pylint/mod.rs index 82ac3e238b..6d154d380e 100644 --- a/src/pylint/mod.rs +++ b/src/pylint/mod.rs @@ -1,4 +1,4 @@ -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { @@ -9,7 +9,7 @@ mod tests { use crate::linter::test_path; use crate::registry::RuleCode; - use crate::Settings; + use crate::settings::Settings; #[test_case(RuleCode::PLC0414, Path::new("import_aliasing.py"); "PLC0414")] #[test_case(RuleCode::PLC2201, Path::new("misplaced_comparison_constant.py"); "PLC2201")] diff --git a/src/pylint/rules/await_outside_async.rs b/src/pylint/rules/await_outside_async.rs index 9b8297eb89..b9fe36a138 100644 --- a/src/pylint/rules/await_outside_async.rs +++ b/src/pylint/rules/await_outside_async.rs @@ -2,7 +2,8 @@ use rustpython_ast::Expr; use crate::ast::types::{FunctionDef, Range, ScopeKind}; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::registry::Diagnostic; +use crate::violations; /// PLE1142 pub fn await_outside_async(checker: &mut Checker, expr: &Expr) { diff --git a/src/pylint/rules/merge_isinstance.rs b/src/pylint/rules/merge_isinstance.rs index 6d7a2cb5cb..a540585b10 100644 --- a/src/pylint/rules/merge_isinstance.rs +++ b/src/pylint/rules/merge_isinstance.rs @@ -4,7 +4,8 @@ use rustpython_ast::{Boolop, Expr, ExprKind}; use crate::ast::types::Range; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::registry::Diagnostic; +use crate::violations; /// PLR1701 pub fn merge_isinstance(checker: &mut Checker, expr: &Expr, op: &Boolop, values: &[Expr]) { diff --git a/src/pylint/rules/misplaced_comparison_constant.rs b/src/pylint/rules/misplaced_comparison_constant.rs index 74c3a357ae..36e3545963 100644 --- a/src/pylint/rules/misplaced_comparison_constant.rs +++ b/src/pylint/rules/misplaced_comparison_constant.rs @@ -1,9 +1,10 @@ use rustpython_ast::{Cmpop, Expr, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::fix::Fix; +use crate::registry::Diagnostic; +use crate::violations; /// PLC2201 pub fn misplaced_comparison_constant( diff --git a/src/pylint/rules/property_with_parameters.rs b/src/pylint/rules/property_with_parameters.rs index a0c6c53a49..d07eb9b9bc 100644 --- a/src/pylint/rules/property_with_parameters.rs +++ b/src/pylint/rules/property_with_parameters.rs @@ -2,7 +2,8 @@ use rustpython_ast::{Arguments, Expr, ExprKind, Stmt}; use crate::ast::types::Range; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::registry::Diagnostic; +use crate::violations; /// PLR0206 pub fn property_with_parameters( diff --git a/src/pylint/rules/unnecessary_direct_lambda_call.rs b/src/pylint/rules/unnecessary_direct_lambda_call.rs index 454386bc10..dd04197342 100644 --- a/src/pylint/rules/unnecessary_direct_lambda_call.rs +++ b/src/pylint/rules/unnecessary_direct_lambda_call.rs @@ -2,7 +2,8 @@ use rustpython_ast::{Expr, ExprKind}; use crate::ast::types::Range; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::registry::Diagnostic; +use crate::violations; /// PLC3002 pub fn unnecessary_direct_lambda_call(checker: &mut Checker, expr: &Expr, func: &Expr) { diff --git a/src/pylint/rules/use_from_import.rs b/src/pylint/rules/use_from_import.rs index ea6ddc0f9b..250deb2c7c 100644 --- a/src/pylint/rules/use_from_import.rs +++ b/src/pylint/rules/use_from_import.rs @@ -2,7 +2,8 @@ use rustpython_ast::Alias; use crate::ast::types::Range; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::registry::Diagnostic; +use crate::violations; /// PLR0402 pub fn use_from_import(checker: &mut Checker, alias: &Alias) { diff --git a/src/pylint/rules/use_sys_exit.rs b/src/pylint/rules/use_sys_exit.rs index 2c99719dcb..6a2bcdff1f 100644 --- a/src/pylint/rules/use_sys_exit.rs +++ b/src/pylint/rules/use_sys_exit.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Expr, ExprKind}; use crate::ast::types::{BindingKind, Range}; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pylint/rules/used_prior_global_declaration.rs b/src/pylint/rules/used_prior_global_declaration.rs index 2f5105b159..8be01aaaa8 100644 --- a/src/pylint/rules/used_prior_global_declaration.rs +++ b/src/pylint/rules/used_prior_global_declaration.rs @@ -2,7 +2,8 @@ use rustpython_ast::Expr; use crate::ast::types::{Range, ScopeKind}; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::registry::Diagnostic; +use crate::violations; /// PLE0118 pub fn used_prior_global_declaration(checker: &mut Checker, name: &str, expr: &Expr) { diff --git a/src/pylint/rules/useless_else_on_loop.rs b/src/pylint/rules/useless_else_on_loop.rs index f5813e8506..3ee4d8e30a 100644 --- a/src/pylint/rules/useless_else_on_loop.rs +++ b/src/pylint/rules/useless_else_on_loop.rs @@ -2,7 +2,8 @@ use rustpython_ast::{ExcepthandlerKind, Stmt, StmtKind}; use crate::ast::helpers; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::registry::Diagnostic; +use crate::violations; fn loop_exits_early(body: &[Stmt]) -> bool { body.iter().any(|stmt| match &stmt.node { diff --git a/src/pylint/rules/useless_import_alias.rs b/src/pylint/rules/useless_import_alias.rs index 2e73e9bbfb..864da7149f 100644 --- a/src/pylint/rules/useless_import_alias.rs +++ b/src/pylint/rules/useless_import_alias.rs @@ -1,9 +1,10 @@ use rustpython_ast::Alias; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; -use crate::{violations, Diagnostic}; +use crate::fix::Fix; +use crate::registry::Diagnostic; +use crate::violations; /// PLC0414 pub fn useless_import_alias(checker: &mut Checker, alias: &Alias) { diff --git a/src/pyupgrade/fixes.rs b/src/pyupgrade/fixes.rs index 7692aaf26d..c6c86678ac 100644 --- a/src/pyupgrade/fixes.rs +++ b/src/pyupgrade/fixes.rs @@ -6,12 +6,12 @@ use rustpython_parser::lexer; use rustpython_parser::lexer::Tok; use crate::ast::types::Range; -use crate::autofix::Fix; -use crate::source_code_locator::SourceCodeLocator; +use crate::fix::Fix; +use crate::source_code::Locator; /// Generate a fix to remove a base from a `ClassDef` statement. pub fn remove_class_def_base( - locator: &SourceCodeLocator, + locator: &Locator, stmt_at: Location, expr_at: Location, bases: &[Expr], @@ -101,7 +101,7 @@ pub fn remove_class_def_base( } /// Generate a fix to remove arguments from a `super` call. -pub fn remove_super_arguments(locator: &SourceCodeLocator, expr: &Expr) -> Option { +pub fn remove_super_arguments(locator: &Locator, expr: &Expr) -> Option { let range = Range::from_located(expr); let contents = locator.slice_source_code_range(&range); diff --git a/src/pyupgrade/mod.rs b/src/pyupgrade/mod.rs index 96ef365950..16c3eb721b 100644 --- a/src/pyupgrade/mod.rs +++ b/src/pyupgrade/mod.rs @@ -1,7 +1,7 @@ -pub mod fixes; -pub mod rules; +mod fixes; +pub(crate) mod rules; pub mod settings; -pub mod types; +pub(crate) mod types; #[cfg(test)] mod tests { diff --git a/src/pyupgrade/rules/convert_named_tuple_functional_to_class.rs b/src/pyupgrade/rules/convert_named_tuple_functional_to_class.rs index 64172ff0b8..2985c61c93 100644 --- a/src/pyupgrade/rules/convert_named_tuple_functional_to_class.rs +++ b/src/pyupgrade/rules/convert_named_tuple_functional_to_class.rs @@ -4,12 +4,12 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtK use crate::ast::helpers::{create_expr, create_stmt, match_module_member, unparse_stmt}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::python::identifiers::IDENTIFIER_REGEX; use crate::python::keyword::KWLIST; use crate::registry::Diagnostic; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::Stylist; use crate::violations; /// Return the typename, args, keywords, and base class. @@ -136,7 +136,7 @@ fn convert_to_class( typename: &str, body: Vec, base_class: &Expr, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> Fix { Fix::replacement( unparse_stmt(&create_class_def_stmt(typename, body, base_class), stylist), diff --git a/src/pyupgrade/rules/convert_typed_dict_functional_to_class.rs b/src/pyupgrade/rules/convert_typed_dict_functional_to_class.rs index f62bb7e1d0..156c5ea84f 100644 --- a/src/pyupgrade/rules/convert_typed_dict_functional_to_class.rs +++ b/src/pyupgrade/rules/convert_typed_dict_functional_to_class.rs @@ -4,12 +4,12 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtK use crate::ast::helpers::{create_expr, create_stmt, match_module_member, unparse_stmt}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::python::identifiers::IDENTIFIER_REGEX; use crate::python::keyword::KWLIST; use crate::registry::Diagnostic; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::Stylist; use crate::violations; /// Return the class name, arguments, keywords and base class for a `TypedDict` @@ -175,7 +175,7 @@ fn convert_to_class( body: Vec, total_keyword: Option<&Keyword>, base_class: &Expr, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> Fix { Fix::replacement( unparse_stmt( diff --git a/src/pyupgrade/rules/datetime_utc_alias.rs b/src/pyupgrade/rules/datetime_utc_alias.rs index a6d741867a..6e231665ec 100644 --- a/src/pyupgrade/rules/datetime_utc_alias.rs +++ b/src/pyupgrade/rules/datetime_utc_alias.rs @@ -2,8 +2,8 @@ use rustpython_ast::Expr; use crate::ast::helpers::{collect_call_paths, compose_call_path, dealias_call_path}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/pyupgrade/rules/deprecated_unittest_alias.rs b/src/pyupgrade/rules/deprecated_unittest_alias.rs index 5ab6c79f07..42e35336fc 100644 --- a/src/pyupgrade/rules/deprecated_unittest_alias.rs +++ b/src/pyupgrade/rules/deprecated_unittest_alias.rs @@ -3,8 +3,8 @@ use rustc_hash::FxHashMap; use rustpython_ast::{Expr, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/format_literals.rs b/src/pyupgrade/rules/format_literals.rs index 569b48311e..f11d0cb750 100644 --- a/src/pyupgrade/rules/format_literals.rs +++ b/src/pyupgrade/rules/format_literals.rs @@ -5,9 +5,9 @@ use regex::Regex; use rustpython_ast::Expr; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; use crate::cst::matchers::{match_call, match_expression}; +use crate::fix::Fix; use crate::pyflakes::format::FormatSummary; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/mod.rs b/src/pyupgrade/rules/mod.rs index ae5e10ad04..e3af3e5337 100644 --- a/src/pyupgrade/rules/mod.rs +++ b/src/pyupgrade/rules/mod.rs @@ -33,7 +33,7 @@ pub(crate) use useless_object_inheritance::useless_object_inheritance; use crate::ast::helpers::{self}; use crate::ast::types::{Range, Scope, ScopeKind}; -use crate::autofix::Fix; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/native_literals.rs b/src/pyupgrade/rules/native_literals.rs index ca92e7f384..72efad44a5 100644 --- a/src/pyupgrade/rules/native_literals.rs +++ b/src/pyupgrade/rules/native_literals.rs @@ -3,8 +3,8 @@ use rustpython_parser::lexer; use rustpython_parser::lexer::Tok; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; use crate::violations::LiteralType; diff --git a/src/pyupgrade/rules/open_alias.rs b/src/pyupgrade/rules/open_alias.rs index 89aa70e4d9..7a2ae745a5 100644 --- a/src/pyupgrade/rules/open_alias.rs +++ b/src/pyupgrade/rules/open_alias.rs @@ -2,8 +2,8 @@ use rustpython_ast::Expr; use crate::ast::helpers::{collect_call_paths, dealias_call_path, match_call_path}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/pyupgrade/rules/os_error_alias.rs b/src/pyupgrade/rules/os_error_alias.rs index ab5139ea84..59f7ee4136 100644 --- a/src/pyupgrade/rules/os_error_alias.rs +++ b/src/pyupgrade/rules/os_error_alias.rs @@ -3,8 +3,8 @@ use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Located}; use crate::ast::helpers::{compose_call_path, match_module_member}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/redundant_open_modes.rs b/src/pyupgrade/rules/redundant_open_modes.rs index 63967165ef..4fa47b3280 100644 --- a/src/pyupgrade/rules/redundant_open_modes.rs +++ b/src/pyupgrade/rules/redundant_open_modes.rs @@ -8,10 +8,10 @@ use rustpython_parser::token::Tok; use crate::ast::helpers::find_keyword; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; const OPEN_FUNC_NAME: &str = "open"; @@ -77,7 +77,7 @@ fn create_check( expr: &Expr, mode_param: &Expr, replacement_value: Option, - locator: &SourceCodeLocator, + locator: &Locator, patch: bool, ) -> Diagnostic { let mut diagnostic = Diagnostic::new( @@ -103,11 +103,7 @@ fn create_check( diagnostic } -fn create_remove_param_fix( - locator: &SourceCodeLocator, - expr: &Expr, - mode_param: &Expr, -) -> Result { +fn create_remove_param_fix(locator: &Locator, expr: &Expr, mode_param: &Expr) -> Result { let content = locator.slice_source_code_range(&Range::new(expr.location, expr.end_location.unwrap())); // Find the last comma before mode_param and create a deletion fix diff --git a/src/pyupgrade/rules/remove_six_compat.rs b/src/pyupgrade/rules/remove_six_compat.rs index 069a60ad61..bbea35a6c3 100644 --- a/src/pyupgrade/rules/remove_six_compat.rs +++ b/src/pyupgrade/rules/remove_six_compat.rs @@ -2,12 +2,11 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, StmtKind}; use crate::ast::helpers::{collect_call_paths, create_expr, create_stmt, dealias_call_path}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; -use crate::source_code_generator::SourceCodeGenerator; -use crate::source_code_style::SourceCodeStyleDetector; -use crate::{violations, SourceCodeLocator}; +use crate::source_code::{Generator, Locator, Stylist}; +use crate::violations; /// Return `true` if the `Expr` is a reference to `${module}.${any}`. fn is_module_member(call_path: &[&str], module: &str) -> bool { @@ -55,7 +54,7 @@ fn replace_by_str_literal( binary: bool, expr: &Expr, patch: bool, - locator: &SourceCodeLocator, + locator: &Locator, ) -> Option { match &arg.node { ExprKind::Constant { .. } => { @@ -88,7 +87,7 @@ fn replace_call_on_arg_by_arg_attribute( arg: &Expr, expr: &Expr, patch: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> Diagnostic { let attribute = ExprKind::Attribute { value: Box::new(arg.clone()), @@ -104,7 +103,7 @@ fn replace_call_on_arg_by_arg_method_call( args: &[Expr], expr: &Expr, patch: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> Option { if args.is_empty() { None @@ -128,15 +127,10 @@ fn replace_call_on_arg_by_arg_method_call( } // `expr` => `Expr(expr_kind)` -fn replace_by_expr_kind( - node: ExprKind, - expr: &Expr, - patch: bool, - stylist: &SourceCodeStyleDetector, -) -> Diagnostic { +fn replace_by_expr_kind(node: ExprKind, expr: &Expr, patch: bool, stylist: &Stylist) -> Diagnostic { let mut diagnostic = Diagnostic::new(violations::RemoveSixCompat, Range::from_located(expr)); if patch { - let mut generator: SourceCodeGenerator = stylist.into(); + let mut generator: Generator = stylist.into(); generator.unparse_expr(&create_expr(node), 0); diagnostic.amend(Fix::replacement( generator.generate(), @@ -147,15 +141,10 @@ fn replace_by_expr_kind( diagnostic } -fn replace_by_stmt_kind( - node: StmtKind, - expr: &Expr, - patch: bool, - stylist: &SourceCodeStyleDetector, -) -> Diagnostic { +fn replace_by_stmt_kind(node: StmtKind, expr: &Expr, patch: bool, stylist: &Stylist) -> Diagnostic { let mut diagnostic = Diagnostic::new(violations::RemoveSixCompat, Range::from_located(expr)); if patch { - let mut generator: SourceCodeGenerator = stylist.into(); + let mut generator: Generator = stylist.into(); generator.unparse_stmt(&create_stmt(node)); diagnostic.amend(Fix::replacement( generator.generate(), @@ -172,7 +161,7 @@ fn replace_by_raise_from( cause: Option, expr: &Expr, patch: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> Diagnostic { let stmt_kind = StmtKind::Raise { exc: exc.map(|exc| Box::new(create_expr(exc))), @@ -186,7 +175,7 @@ fn replace_by_index_on_arg( index: &ExprKind, expr: &Expr, patch: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> Diagnostic { let index = ExprKind::Subscript { value: Box::new(create_expr(arg.node.clone())), @@ -200,7 +189,7 @@ fn handle_reraise( args: &[Expr], expr: &Expr, patch: bool, - stylist: &SourceCodeStyleDetector, + stylist: &Stylist, ) -> Option { if let [_, exc, tb] = args { Some(replace_by_raise_from( @@ -242,8 +231,8 @@ fn handle_func( keywords: &[Keyword], expr: &Expr, patch: bool, - stylist: &SourceCodeStyleDetector, - locator: &SourceCodeLocator, + stylist: &Stylist, + locator: &Locator, ) -> Option { let func_name = match &func.node { ExprKind::Attribute { attr, .. } => attr, diff --git a/src/pyupgrade/rules/replace_stdout_stderr.rs b/src/pyupgrade/rules/replace_stdout_stderr.rs index 03ea1b6124..33bfe3cf88 100644 --- a/src/pyupgrade/rules/replace_stdout_stderr.rs +++ b/src/pyupgrade/rules/replace_stdout_stderr.rs @@ -3,8 +3,8 @@ use rustpython_ast::{Expr, Keyword}; use crate::ast::helpers::{find_keyword, match_module_member}; use crate::ast::types::Range; use crate::ast::whitespace::indentation; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/replace_universal_newlines.rs b/src/pyupgrade/rules/replace_universal_newlines.rs index 78885f391e..bc797d6f04 100644 --- a/src/pyupgrade/rules/replace_universal_newlines.rs +++ b/src/pyupgrade/rules/replace_universal_newlines.rs @@ -2,8 +2,8 @@ use rustpython_ast::{Expr, Keyword, Location}; use crate::ast::helpers::{find_keyword, match_module_member}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/rewrite_c_element_tree.rs b/src/pyupgrade/rules/rewrite_c_element_tree.rs index b60daab071..f5fd33aa3a 100644 --- a/src/pyupgrade/rules/rewrite_c_element_tree.rs +++ b/src/pyupgrade/rules/rewrite_c_element_tree.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Located, Stmt, StmtKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/rewrite_mock_import.rs b/src/pyupgrade/rules/rewrite_mock_import.rs index b9c975c5d3..5273a6c6f1 100644 --- a/src/pyupgrade/rules/rewrite_mock_import.rs +++ b/src/pyupgrade/rules/rewrite_mock_import.rs @@ -9,12 +9,11 @@ use rustpython_ast::{Expr, ExprKind, Stmt, StmtKind}; use crate::ast::helpers::collect_call_paths; use crate::ast::types::Range; use crate::ast::whitespace::indentation; -use crate::autofix::Fix; use crate::checkers::ast::Checker; use crate::cst::matchers::{match_import, match_import_from, match_module}; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; -use crate::source_code_locator::SourceCodeLocator; -use crate::source_code_style::SourceCodeStyleDetector; +use crate::source_code::{Locator, Stylist}; use crate::violations; use crate::violations::MockReference; @@ -84,11 +83,7 @@ fn includes_mock_member(aliases: &[ImportAlias]) -> bool { false } -fn format_mocks( - aliases: Vec>, - indent: &str, - stylist: &SourceCodeStyleDetector, -) -> String { +fn format_mocks(aliases: Vec>, indent: &str, stylist: &Stylist) -> String { let mut content = String::new(); for alias in aliases { match alias { @@ -118,8 +113,8 @@ fn format_mocks( fn format_import( stmt: &Stmt, indent: &str, - locator: &SourceCodeLocator, - stylist: &SourceCodeStyleDetector, + locator: &Locator, + stylist: &Stylist, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(stmt)); let mut tree = match_module(&module_text)?; @@ -148,8 +143,8 @@ fn format_import( fn format_import_from( stmt: &Stmt, indent: &str, - locator: &SourceCodeLocator, - stylist: &SourceCodeStyleDetector, + locator: &Locator, + stylist: &Stylist, ) -> Result { let module_text = locator.slice_source_code_range(&Range::from_located(stmt)); let mut tree = match_module(&module_text).unwrap(); diff --git a/src/pyupgrade/rules/rewrite_unicode_literal.rs b/src/pyupgrade/rules/rewrite_unicode_literal.rs index de724dcc34..893dac2fa0 100644 --- a/src/pyupgrade/rules/rewrite_unicode_literal.rs +++ b/src/pyupgrade/rules/rewrite_unicode_literal.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Expr, Location}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/rewrite_yield_from.rs b/src/pyupgrade/rules/rewrite_yield_from.rs index b1c5c5224b..5513eeb9fc 100644 --- a/src/pyupgrade/rules/rewrite_yield_from.rs +++ b/src/pyupgrade/rules/rewrite_yield_from.rs @@ -4,8 +4,8 @@ use rustpython_ast::{Expr, ExprContext, ExprKind, Stmt, StmtKind}; use crate::ast::types::{Range, RefEquality}; use crate::ast::visitor; use crate::ast::visitor::Visitor; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/type_of_primitive.rs b/src/pyupgrade/rules/type_of_primitive.rs index 1acfaa2643..c71bf47d2c 100644 --- a/src/pyupgrade/rules/type_of_primitive.rs +++ b/src/pyupgrade/rules/type_of_primitive.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Expr, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::pyupgrade::types::Primitive; use crate::registry::{Diagnostic, DiagnosticKind}; use crate::violations; diff --git a/src/pyupgrade/rules/typing_text_str_alias.rs b/src/pyupgrade/rules/typing_text_str_alias.rs index 0b8dfcd93c..95eb059fab 100644 --- a/src/pyupgrade/rules/typing_text_str_alias.rs +++ b/src/pyupgrade/rules/typing_text_str_alias.rs @@ -2,8 +2,8 @@ use rustpython_ast::Expr; use crate::ast::helpers::match_module_member; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/unnecessary_encode_utf8.rs b/src/pyupgrade/rules/unnecessary_encode_utf8.rs index 92df901c96..c6e189d0bb 100644 --- a/src/pyupgrade/rules/unnecessary_encode_utf8.rs +++ b/src/pyupgrade/rules/unnecessary_encode_utf8.rs @@ -1,10 +1,10 @@ use rustpython_ast::{Constant, Expr, ExprKind, Keyword}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::violations; const UTF8_LITERALS: &[&str] = &["utf-8", "utf8", "utf_8", "u8", "utf", "cp65001"]; @@ -82,7 +82,7 @@ fn delete_default_encode_arg_or_kwarg( fn replace_with_bytes_literal( expr: &Expr, constant: &Expr, - locator: &SourceCodeLocator, + locator: &Locator, patch: bool, ) -> Diagnostic { let mut diagnostic = diff --git a/src/pyupgrade/rules/unnecessary_lru_cache_params.rs b/src/pyupgrade/rules/unnecessary_lru_cache_params.rs index e97d13ad73..8c91f0a161 100644 --- a/src/pyupgrade/rules/unnecessary_lru_cache_params.rs +++ b/src/pyupgrade/rules/unnecessary_lru_cache_params.rs @@ -4,8 +4,8 @@ use rustpython_parser::ast::Expr; use crate::ast::helpers; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::settings::types::PythonVersion; use crate::violations; diff --git a/src/pyupgrade/rules/unpack_list_comprehension.rs b/src/pyupgrade/rules/unpack_list_comprehension.rs index 7d9dd0e4fe..efa01e6c68 100644 --- a/src/pyupgrade/rules/unpack_list_comprehension.rs +++ b/src/pyupgrade/rules/unpack_list_comprehension.rs @@ -1,8 +1,8 @@ use rustpython_ast::{Expr, ExprKind}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::{Diagnostic, RuleCode}; use crate::violations; diff --git a/src/pyupgrade/rules/use_pep585_annotation.rs b/src/pyupgrade/rules/use_pep585_annotation.rs index fcb8c6e80a..b26f532e83 100644 --- a/src/pyupgrade/rules/use_pep585_annotation.rs +++ b/src/pyupgrade/rules/use_pep585_annotation.rs @@ -1,8 +1,8 @@ use rustpython_ast::Expr; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; use crate::violations; diff --git a/src/pyupgrade/rules/use_pep604_annotation.rs b/src/pyupgrade/rules/use_pep604_annotation.rs index 26a4337560..bd6923b006 100644 --- a/src/pyupgrade/rules/use_pep604_annotation.rs +++ b/src/pyupgrade/rules/use_pep604_annotation.rs @@ -2,10 +2,10 @@ use rustpython_ast::{Constant, Expr, ExprKind, Location, Operator}; use crate::ast::helpers::{collect_call_paths, dealias_call_path}; use crate::ast::types::Range; -use crate::autofix::Fix; use crate::checkers::ast::Checker; +use crate::fix::Fix; use crate::registry::Diagnostic; -use crate::source_code_generator::SourceCodeGenerator; +use crate::source_code::Generator; use crate::violations; fn optional(expr: &Expr) -> Expr { @@ -67,7 +67,7 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s let mut diagnostic = Diagnostic::new(violations::UsePEP604Annotation, Range::from_located(expr)); if checker.patch(diagnostic.kind.code()) { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr(&optional(slice), 0); diagnostic.amend(Fix::replacement( generator.generate(), @@ -85,7 +85,7 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s // Invalid type annotation. } ExprKind::Tuple { elts, .. } => { - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr(&union(elts), 0); diagnostic.amend(Fix::replacement( generator.generate(), @@ -95,7 +95,7 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s } _ => { // Single argument. - let mut generator: SourceCodeGenerator = checker.style.into(); + let mut generator: Generator = checker.style.into(); generator.unparse_expr(slice, 0); diagnostic.amend(Fix::replacement( generator.generate(), diff --git a/src/registry.rs b/src/registry.rs index fedc846abf..83f8034345 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use strum_macros::{AsRefStr, Display, EnumIter, EnumString}; use crate::ast::types::Range; -use crate::autofix::Fix; +use crate::fix::Fix; use crate::violation::Violation; use crate::violations; diff --git a/src/ruff/mod.rs b/src/ruff/mod.rs index 93080df618..6f9208bc20 100644 --- a/src/ruff/mod.rs +++ b/src/ruff/mod.rs @@ -1,6 +1,6 @@ //! Module for Ruff-specific rules. -pub mod rules; +pub(crate) mod rules; #[cfg(test)] mod tests { diff --git a/src/ruff/rules.rs b/src/ruff/rules.rs index c6f9c9db54..f90b66cb71 100644 --- a/src/ruff/rules.rs +++ b/src/ruff/rules.rs @@ -3,11 +3,11 @@ use rustc_hash::FxHashMap; use rustpython_ast::{Expr, ExprKind, Keyword, KeywordData, Location}; use crate::ast::types::Range; -use crate::autofix::Fix; -use crate::registry::DiagnosticKind; -use crate::settings::flags; -use crate::source_code_locator::SourceCodeLocator; -use crate::{violations, Diagnostic, Settings}; +use crate::fix::Fix; +use crate::registry::{Diagnostic, DiagnosticKind}; +use crate::settings::{flags, Settings}; +use crate::source_code::Locator; +use crate::violations; /// See: static CONFUSABLES: Lazy> = Lazy::new(|| { @@ -1605,7 +1605,7 @@ pub enum Context { } pub fn ambiguous_unicode_character( - locator: &SourceCodeLocator, + locator: &Locator, start: Location, end: Location, context: Context, diff --git a/src/settings/flags.rs b/src/settings/flags.rs index b6c9128d62..cfb47464d0 100644 --- a/src/settings/flags.rs +++ b/src/settings/flags.rs @@ -1,5 +1,4 @@ -/// Simple flags used to drive program behavior. -use crate::autofix::fixer; +use crate::fix; #[derive(Debug, Copy, Clone, Hash)] pub enum Autofix { @@ -17,11 +16,11 @@ impl From for Autofix { } } -impl From for Autofix { - fn from(value: fixer::Mode) -> Self { +impl From for Autofix { + fn from(value: fix::FixMode) -> Self { match value { - fixer::Mode::Generate | fixer::Mode::Diff | fixer::Mode::Apply => Autofix::Enabled, - fixer::Mode::None => Autofix::Disabled, + fix::FixMode::Generate | fix::FixMode::Diff | fix::FixMode::Apply => Autofix::Enabled, + fix::FixMode::None => Autofix::Disabled, } } } diff --git a/src/settings/mod.rs b/src/settings/mod.rs index b3450b3d6a..3c9f7412d5 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -29,11 +29,12 @@ use crate::{ }; pub mod configuration; -pub mod flags; +pub(crate) mod flags; pub mod options; pub mod options_base; pub mod pyproject; pub mod types; + const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); #[derive(Debug)] diff --git a/src/source_code_generator.rs b/src/source_code/generator.rs similarity index 97% rename from src/source_code_generator.rs rename to src/source_code/generator.rs index 5d4c10360e..560ec5fb19 100644 --- a/src/source_code_generator.rs +++ b/src/source_code/generator.rs @@ -9,7 +9,7 @@ use rustpython_parser::ast::{ Operator, Stmt, StmtKind, }; -use crate::source_code_style::{Indentation, LineEnding, Quote, SourceCodeStyleDetector}; +use crate::source_code::stylist::{Indentation, LineEnding, Quote, Stylist}; use crate::vendor::{bytes, str}; mod precedence { @@ -30,7 +30,7 @@ mod precedence { pub const EXPR: u8 = BOR; } -pub struct SourceCodeGenerator<'a> { +pub struct Generator<'a> { /// The indentation style to use. indent: &'a Indentation, /// The quote style to use for string literals. @@ -43,8 +43,8 @@ pub struct SourceCodeGenerator<'a> { initial: bool, } -impl<'a> From<&'a SourceCodeStyleDetector<'a>> for SourceCodeGenerator<'a> { - fn from(stylist: &'a SourceCodeStyleDetector<'a>) -> Self { +impl<'a> From<&'a Stylist<'a>> for Generator<'a> { + fn from(stylist: &'a Stylist<'a>) -> Self { Self { indent: stylist.indentation(), quote: stylist.quote(), @@ -57,9 +57,9 @@ impl<'a> From<&'a SourceCodeStyleDetector<'a>> for SourceCodeGenerator<'a> { } } -impl<'a> SourceCodeGenerator<'a> { +impl<'a> Generator<'a> { pub fn new(indent: &'a Indentation, quote: &'a Quote, line_ending: &'a LineEnding) -> Self { - SourceCodeGenerator { + Generator { // Style preferences. indent, quote, @@ -962,7 +962,7 @@ impl<'a> SourceCodeGenerator<'a> { } fn unparse_formatted(&mut self, val: &Expr, conversion: usize, spec: Option<&Expr>) { - let mut generator = SourceCodeGenerator::new(self.indent, self.quote, self.line_ending); + let mut generator = Generator::new(self.indent, self.quote, self.line_ending); generator.unparse_expr(val, precedence::TEST + 1); let brace = if generator.buffer.starts_with('{') { // put a space to avoid escaping the bracket @@ -1016,7 +1016,7 @@ impl<'a> SourceCodeGenerator<'a> { self.unparse_fstring_body(values, is_spec); } else { self.p("f"); - let mut generator = SourceCodeGenerator::new(self.indent, self.quote, self.line_ending); + let mut generator = Generator::new(self.indent, self.quote, self.line_ending); generator.unparse_fstring_body(values, is_spec); let body = &generator.buffer; self.p(&format!("{}", str::repr(body, self.quote.into()))); @@ -1045,8 +1045,8 @@ mod tests { use rustpython_parser::parser; - use crate::source_code_generator::SourceCodeGenerator; - use crate::source_code_style::{Indentation, LineEnding, Quote}; + use crate::source_code::stylist::{Indentation, LineEnding, Quote}; + use crate::source_code::Generator; fn round_trip(contents: &str) -> String { let indentation = Indentation::default(); @@ -1054,7 +1054,7 @@ mod tests { let line_ending = LineEnding::default(); let program = parser::parse_program(contents, "").unwrap(); let stmt = program.first().unwrap(); - let mut generator = SourceCodeGenerator::new(&indentation, "e, &line_ending); + let mut generator = Generator::new(&indentation, "e, &line_ending); generator.unparse_stmt(stmt); generator.generate() } @@ -1067,7 +1067,7 @@ mod tests { ) -> String { let program = parser::parse_program(contents, "").unwrap(); let stmt = program.first().unwrap(); - let mut generator = SourceCodeGenerator::new(indentation, quote, line_ending); + let mut generator = Generator::new(indentation, quote, line_ending); generator.unparse_stmt(stmt); generator.generate() } diff --git a/src/source_code_locator.rs b/src/source_code/locator.rs similarity index 95% rename from src/source_code_locator.rs rename to src/source_code/locator.rs index 52e639dc56..6e94d4fddb 100644 --- a/src/source_code_locator.rs +++ b/src/source_code/locator.rs @@ -8,14 +8,14 @@ use rustpython_ast::Location; use crate::ast::types::Range; -pub struct SourceCodeLocator<'a> { +pub struct Locator<'a> { contents: &'a str, rope: OnceCell, } -impl<'a> SourceCodeLocator<'a> { +impl<'a> Locator<'a> { pub fn new(contents: &'a str) -> Self { - SourceCodeLocator { + Locator { contents, rope: OnceCell::default(), } diff --git a/src/source_code/mod.rs b/src/source_code/mod.rs new file mode 100644 index 0000000000..769fea16c7 --- /dev/null +++ b/src/source_code/mod.rs @@ -0,0 +1,7 @@ +mod generator; +mod locator; +mod stylist; + +pub use generator::Generator; +pub use locator::Locator; +pub use stylist::{LineEnding, Stylist}; diff --git a/src/source_code_style.rs b/src/source_code/stylist.rs similarity index 85% rename from src/source_code_style.rs rename to src/source_code/stylist.rs index 8a83b371cb..081203033b 100644 --- a/src/source_code_style.rs +++ b/src/source_code/stylist.rs @@ -10,18 +10,18 @@ use rustpython_parser::lexer::Tok; use crate::ast::types::Range; use crate::pydocstyle::helpers::leading_quote; -use crate::source_code_locator::SourceCodeLocator; +use crate::source_code::Locator; use crate::vendor; -pub struct SourceCodeStyleDetector<'a> { +pub struct Stylist<'a> { contents: &'a str, - locator: &'a SourceCodeLocator<'a>, + locator: &'a Locator<'a>, indentation: OnceCell, quote: OnceCell, line_ending: OnceCell, } -impl<'a> SourceCodeStyleDetector<'a> { +impl<'a> Stylist<'a> { pub fn indentation(&'a self) -> &'a Indentation { self.indentation .get_or_init(|| detect_indentation(self.contents, self.locator).unwrap_or_default()) @@ -37,7 +37,7 @@ impl<'a> SourceCodeStyleDetector<'a> { .get_or_init(|| detect_line_ending(self.contents).unwrap_or_default()) } - pub fn from_contents(contents: &'a str, locator: &'a SourceCodeLocator<'a>) -> Self { + pub fn from_contents(contents: &'a str, locator: &'a Locator<'a>) -> Self { Self { contents, locator, @@ -71,7 +71,7 @@ impl From<&Quote> for vendor::str::Quote { } impl fmt::Display for Quote { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Quote::Single => write!(f, "\'"), Quote::Double => write!(f, "\""), @@ -140,7 +140,7 @@ impl Deref for LineEnding { } /// Detect the indentation style of the given tokens. -fn detect_indentation(contents: &str, locator: &SourceCodeLocator) -> Option { +fn detect_indentation(contents: &str, locator: &Locator) -> Option { for (_start, tok, end) in lexer::make_tokenizer(contents).flatten() { if let Tok::Indent { .. } = tok { let start = Location::new(end.row(), 0); @@ -152,7 +152,7 @@ fn detect_indentation(contents: &str, locator: &SourceCodeLocator) -> Option Option { +fn detect_quote(contents: &str, locator: &Locator) -> Option { for (start, tok, end) in lexer::make_tokenizer(contents).flatten() { if let Tok::String { .. } = tok { let content = locator.slice_source_code_range(&Range::new(start, end)); @@ -186,22 +186,22 @@ fn detect_line_ending(contents: &str) -> Option { #[cfg(test)] mod tests { - use crate::source_code_style::{ + use crate::source_code::stylist::{ detect_indentation, detect_line_ending, detect_quote, Indentation, LineEnding, Quote, }; - use crate::SourceCodeLocator; + use crate::source_code::Locator; #[test] fn indentation() { let contents = r#"x = 1"#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!(detect_indentation(contents, &locator), None); let contents = r#" if True: pass "#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( detect_indentation(contents, &locator), Some(Indentation(" ".to_string())) @@ -211,7 +211,7 @@ if True: if True: pass "#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( detect_indentation(contents, &locator), Some(Indentation(" ".to_string())) @@ -221,7 +221,7 @@ if True: if True: pass "#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!( detect_indentation(contents, &locator), Some(Indentation("\t".to_string())) @@ -235,22 +235,22 @@ x = ( 3, ) "#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!(detect_indentation(contents, &locator), None); } #[test] fn quote() { let contents = r#"x = 1"#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!(detect_quote(contents, &locator), None); let contents = r#"x = '1'"#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!(detect_quote(contents, &locator), Some(Quote::Single)); let contents = r#"x = "1""#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!(detect_quote(contents, &locator), Some(Quote::Double)); let contents = r#" @@ -258,7 +258,7 @@ def f(): """Docstring.""" pass "#; - let locator = SourceCodeLocator::new(contents); + let locator = Locator::new(contents); assert_eq!(detect_quote(contents, &locator), Some(Quote::Double)); }