From 74e3cdfd7c4f8f8d5cb4691975ca2a75e78a8b29 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 29 Jan 2023 22:38:29 -0500 Subject: [PATCH] Add a dedicated single-fix helper (#2339) --- src/autofix/fixer.rs | 1 - src/autofix/mod.rs | 56 +++++++++++++++++++++++++++++++---- src/rules/pandas_vet/fixes.rs | 4 +-- 3 files changed, 52 insertions(+), 9 deletions(-) delete mode 100644 src/autofix/fixer.rs diff --git a/src/autofix/fixer.rs b/src/autofix/fixer.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/src/autofix/fixer.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/autofix/mod.rs b/src/autofix/mod.rs index bf3368d28b..1f77cbccdc 100644 --- a/src/autofix/mod.rs +++ b/src/autofix/mod.rs @@ -8,7 +8,6 @@ use crate::fix::Fix; use crate::registry::Diagnostic; use crate::source_code::Locator; -pub mod fixer; pub mod helpers; /// Auto-fix errors in a file, and write the fixed source code to disk. @@ -24,7 +23,7 @@ pub fn fix_file(diagnostics: &[Diagnostic], locator: &Locator) -> Option<(String } /// Apply a series of fixes. -pub(crate) fn apply_fixes<'a>( +fn apply_fixes<'a>( fixes: impl Iterator, locator: &'a Locator<'a>, ) -> (String, usize) { @@ -67,11 +66,29 @@ pub(crate) fn apply_fixes<'a>( (output, num_fixed) } +/// Apply a single fix. +pub(crate) fn apply_fix(fix: &Fix, locator: &Locator) -> String { + let mut output = String::new(); + + // Add all contents from `last_pos` to `fix.location`. + let slice = locator.slice_source_code_range(&Range::new(Location::new(1, 0), fix.location)); + output.push_str(slice); + + // Add the patch itself. + output.push_str(&fix.content); + + // Add the remaining content. + let slice = locator.slice_source_code_at(fix.end_location); + output.push_str(slice); + + output +} + #[cfg(test)] mod tests { use rustpython_parser::ast::Location; - use crate::autofix::apply_fixes; + use crate::autofix::{apply_fix, apply_fixes}; use crate::fix::Fix; use crate::source_code::Locator; @@ -85,7 +102,7 @@ mod tests { } #[test] - fn apply_single_replacement() { + fn apply_one_replacement() { let fixes = vec![Fix { content: "Bar".to_string(), location: Location::new(1, 8), @@ -111,7 +128,7 @@ class A(Bar): } #[test] - fn apply_single_removal() { + fn apply_one_removal() { let fixes = vec![Fix { content: String::new(), location: Location::new(1, 7), @@ -137,7 +154,7 @@ class A: } #[test] - fn apply_double_removal() { + fn apply_two_removals() { let fixes = vec![ Fix { content: String::new(), @@ -202,4 +219,31 @@ class A: ); assert_eq!(fixed, 1); } + + #[test] + fn apply_single_fix() { + let locator = Locator::new( + r#" +class A(object): + ... +"# + .trim(), + ); + let contents = apply_fix( + &Fix { + content: String::new(), + location: Location::new(1, 7), + end_location: Location::new(1, 15), + }, + &locator, + ); + assert_eq!( + contents, + r#" +class A: + ... +"# + .trim() + ); + } } diff --git a/src/rules/pandas_vet/fixes.rs b/src/rules/pandas_vet/fixes.rs index c4982eb242..1e2cb5c32b 100644 --- a/src/rules/pandas_vet/fixes.rs +++ b/src/rules/pandas_vet/fixes.rs @@ -2,7 +2,7 @@ use crate::ast::helpers; use rustpython_ast::{Expr, ExprKind, Keyword, Location}; use crate::ast::types::Range; -use crate::autofix::apply_fixes; +use crate::autofix::apply_fix; use crate::autofix::helpers::remove_argument; use crate::fix::Fix; use crate::source_code::Locator; @@ -52,7 +52,7 @@ pub fn fix_inplace_argument( // TODO(charlie): Find a way to let contents = locator.slice_source_code_range(&Range::new(expr.location, expr.end_location.unwrap())); - let (output, _) = apply_fixes([fix_me].iter(), &Locator::new(contents)); + let output = apply_fix(&fix_me, &Locator::new(contents)); // Obtain the name prefix. let name = match_name(expr)?;