Abstract stylist to libcst style conversion (#4749)

* Abstract codegen with stylist into a CodegenStylist trait

Replace all duplicate invocations of

```rust
let mut state = CodegenState {
    default_newline: &stylist.line_ending(),
    default_indent: stylist.indentation(),
    ..CodegenState::default()
}
tree.codegen(&mut state);
state.to_string()
```

with

```rust
tree.codegen_stylist(&stylist);
```

No functional changes.
This commit is contained in:
konstin
2023-06-05 09:22:43 +02:00
committed by GitHub
parent 1fba98681e
commit 576e0c7b80
13 changed files with 139 additions and 303 deletions

View File

@@ -11,6 +11,23 @@ use ruff_python_ast::source_code::{Locator, Stylist};
use crate::cst::helpers::compose_module_path;
use crate::cst::matchers::match_statement;
/// Glue code to make libcst codegen work with ruff's Stylist
pub(crate) trait CodegenStylist<'a>: Codegen<'a> {
fn codegen_stylist(&self, stylist: &'a Stylist) -> String;
}
impl<'a, T: Codegen<'a>> CodegenStylist<'a> for T {
fn codegen_stylist(&self, stylist: &'a Stylist) -> String {
let mut state = CodegenState {
default_newline: stylist.line_ending().as_str(),
default_indent: stylist.indentation(),
..Default::default()
};
self.codegen(&mut state);
state.to_string()
}
}
/// Given an import statement, remove any imports that are specified in the `imports` iterator.
///
/// Returns `Ok(None)` if the statement is empty after removing the imports.
@@ -114,14 +131,7 @@ pub(crate) fn remove_imports<'a>(
return Ok(None);
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Some(state.to_string()))
Ok(Some(tree.codegen_stylist(stylist)))
}
/// Given an import statement, remove any imports that are not specified in the `imports` slice.
@@ -200,11 +210,5 @@ pub(crate) fn retain_imports(
}
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(state.to_string())
Ok(tree.codegen_stylist(stylist))
}

View File

@@ -3,11 +3,12 @@
use std::error::Error;
use anyhow::Result;
use libcst_native::{Codegen, CodegenState, ImportAlias, Name, NameOrAttribute};
use libcst_native::{ImportAlias, Name, NameOrAttribute};
use ruff_text_size::TextSize;
use rustpython_parser::ast::{self, Ranged, Stmt, Suite};
use crate::autofix;
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::Edit;
use ruff_python_ast::imports::{AnyImport, Import, ImportFrom};
use ruff_python_ast::source_code::{Locator, Stylist};
@@ -324,13 +325,10 @@ impl<'a> Importer<'a> {
asname: None,
comma: aliases.last().and_then(|alias| alias.comma.clone()),
});
let mut state = CodegenState {
default_newline: &self.stylist.line_ending(),
default_indent: self.stylist.indentation(),
..CodegenState::default()
};
statement.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), stmt.range()))
Ok(Edit::range_replacement(
statement.codegen_stylist(self.stylist),
stmt.range(),
))
}
/// Add a `TYPE_CHECKING` block to the given module.

View File

@@ -1,14 +1,15 @@
use anyhow::{bail, Result};
use itertools::Itertools;
use libcst_native::{
Arg, AssignEqual, AssignTargetExpression, Call, Codegen, CodegenState, Comment, CompFor, Dict,
DictComp, DictElement, Element, EmptyLine, Expression, GeneratorExp, LeftCurlyBrace, LeftParen,
LeftSquareBracket, List, ListComp, Name, ParenthesizableWhitespace, ParenthesizedWhitespace,
RightCurlyBrace, RightParen, RightSquareBracket, Set, SetComp, SimpleString, SimpleWhitespace,
Arg, AssignEqual, AssignTargetExpression, Call, Comment, CompFor, Dict, DictComp, DictElement,
Element, EmptyLine, Expression, GeneratorExp, LeftCurlyBrace, LeftParen, LeftSquareBracket,
List, ListComp, Name, ParenthesizableWhitespace, ParenthesizedWhitespace, RightCurlyBrace,
RightParen, RightSquareBracket, Set, SetComp, SimpleString, SimpleWhitespace,
TrailingWhitespace, Tuple,
};
use rustpython_parser::ast::Ranged;
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::{Edit, Fix};
use ruff_python_ast::source_code::{Locator, Stylist};
@@ -44,14 +45,10 @@ pub(crate) fn fix_unnecessary_generator_list(
rpar: generator_exp.rpar.clone(),
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C401) Convert `set(x for x in y)` to `{x for x in y}`.
@@ -82,14 +79,7 @@ pub(crate) fn fix_unnecessary_generator_set(
rpar: generator_exp.rpar.clone(),
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
let mut content = state.to_string();
let mut content = tree.codegen_stylist(stylist);
// If the expression is embedded in an f-string, surround it with spaces to avoid
// syntax errors.
@@ -136,14 +126,7 @@ pub(crate) fn fix_unnecessary_generator_dict(
whitespace_after_colon: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" ")),
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
let mut content = state.to_string();
let mut content = tree.codegen_stylist(stylist);
// If the expression is embedded in an f-string, surround it with spaces to avoid
// syntax errors.
@@ -182,14 +165,10 @@ pub(crate) fn fix_unnecessary_list_comprehension_set(
rpar: list_comp.rpar.clone(),
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C404) Convert `dict([(i, i) for i in range(3)])` to `{i: i for i in
@@ -229,14 +208,10 @@ pub(crate) fn fix_unnecessary_list_comprehension_dict(
rpar: list_comp.rpar.clone(),
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// Drop a trailing comma from a list of tuple elements.
@@ -318,14 +293,10 @@ pub(crate) fn fix_unnecessary_literal_set(
}));
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C406) Convert `dict([(1, 2)])` to `{1: 2}`.
@@ -386,14 +357,10 @@ pub(crate) fn fix_unnecessary_literal_dict(
rpar: vec![],
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C408)
@@ -495,14 +462,10 @@ pub(crate) fn fix_unnecessary_collection_call(
}
};
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C409) Convert `tuple([1, 2])` to `tuple(1, 2)`
@@ -549,14 +512,10 @@ pub(crate) fn fix_unnecessary_literal_within_tuple_call(
}],
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C410) Convert `list([1, 2])` to `[1, 2]`
@@ -605,14 +564,10 @@ pub(crate) fn fix_unnecessary_literal_within_list_call(
rpar: vec![],
}));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C411) Convert `list([i * i for i in x])` to `[i * i for i in x]`.
@@ -629,14 +584,10 @@ pub(crate) fn fix_unnecessary_list_call(
tree = arg.value.clone();
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C413) Convert `list(sorted([2, 3, 1]))` to `sorted([2, 3, 1])`.
@@ -747,14 +698,10 @@ pub(crate) fn fix_unnecessary_call_around_sorted(
}
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C414) Convert `sorted(list(foo))` to `sorted(foo)`
@@ -781,14 +728,10 @@ pub(crate) fn fix_unnecessary_double_cast_or_process(
None => bail!("Expected at least one argument in outer function call"),
};
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C416) Convert `[i for i in x]` to `list(x)`.
@@ -872,14 +815,10 @@ pub(crate) fn fix_unnecessary_comprehension(
}
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C417) Convert `map(lambda x: x * 2, bar)` to `(x * 2 for x in bar)`.
@@ -1018,14 +957,7 @@ pub(crate) fn fix_unnecessary_map(
}
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
let mut content = state.to_string();
let mut content = tree.codegen_stylist(stylist);
// If the expression is embedded in an f-string, surround it with spaces to avoid
// syntax errors.
@@ -1054,14 +986,10 @@ pub(crate) fn fix_unnecessary_literal_within_dict_call(
tree = arg.value.clone();
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), expr.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
expr.range(),
))
}
/// (C419) Convert `[i for i in a]` into `i for i in a`
@@ -1231,15 +1159,8 @@ pub(crate) fn fix_unnecessary_comprehension_any_all(
_ => whitespace_after_arg,
};
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Fix::suggested(Edit::range_replacement(
state.to_string(),
tree.codegen_stylist(stylist),
expr.range(),
)))
}

View File

@@ -3,12 +3,13 @@ use std::borrow::Cow;
use anyhow::bail;
use anyhow::Result;
use libcst_native::{
Assert, BooleanOp, Codegen, CodegenState, CompoundStatement, Expression,
ParenthesizableWhitespace, ParenthesizedNode, SimpleStatementLine, SimpleWhitespace,
SmallStatement, Statement, TrailingWhitespace, UnaryOp, UnaryOperation,
Assert, BooleanOp, CompoundStatement, Expression, ParenthesizableWhitespace, ParenthesizedNode,
SimpleStatementLine, SimpleWhitespace, SmallStatement, Statement, TrailingWhitespace, UnaryOp,
UnaryOperation,
};
use rustpython_parser::ast::{self, Boolop, Excepthandler, Expr, Keyword, Ranged, Stmt, Unaryop};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::{has_comments_in, Truthiness};
@@ -410,15 +411,8 @@ fn fix_composite_condition(stmt: &Stmt, locator: &Locator, stylist: &Stylist) ->
}));
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
// Reconstruct and reformat the code.
let module_text = state.to_string();
let module_text = tree.codegen_stylist(stylist);
let contents = if outer_indent.is_empty() {
module_text
} else {

View File

@@ -2,12 +2,12 @@ use std::borrow::Cow;
use anyhow::{bail, Result};
use libcst_native::{
BooleanOp, BooleanOperation, Codegen, CodegenState, CompoundStatement, Expression, If,
LeftParen, ParenthesizableWhitespace, ParenthesizedNode, RightParen, SimpleWhitespace,
Statement, Suite,
BooleanOp, BooleanOperation, CompoundStatement, Expression, If, LeftParen,
ParenthesizableWhitespace, ParenthesizedNode, RightParen, SimpleWhitespace, Statement, Suite,
};
use rustpython_parser::ast::Ranged;
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::Edit;
use ruff_python_ast::source_code::{Locator, Stylist};
use ruff_python_ast::whitespace;
@@ -111,15 +111,8 @@ pub(crate) fn fix_nested_if_statements(
}));
outer_if.body = inner_if.body.clone();
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..Default::default()
};
tree.codegen(&mut state);
// Reconstruct and reformat the code.
let module_text = state.to_string();
let module_text = tree.codegen_stylist(stylist);
let module_text = if outer_indent.is_empty() {
&module_text
} else {

View File

@@ -1,7 +1,8 @@
use anyhow::{bail, Result};
use libcst_native::{Codegen, CodegenState, CompoundStatement, Statement, Suite, With};
use libcst_native::{CompoundStatement, Statement, Suite, With};
use rustpython_parser::ast::Ranged;
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::Edit;
use ruff_python_ast::source_code::{Locator, Stylist};
use ruff_python_ast::whitespace;
@@ -70,15 +71,8 @@ pub(crate) fn fix_multiple_with_statements(
}
outer_with.body = inner_with.body.clone();
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
// Reconstruct and reformat the code.
let module_text = state.to_string();
let module_text = tree.codegen_stylist(stylist);
let contents = if outer_indent.is_empty() {
module_text
} else {

View File

@@ -1,9 +1,10 @@
use anyhow::Result;
use libcst_native::{Codegen, CodegenState};
use log::error;
use ruff_text_size::TextRange;
use rustpython_parser::ast::{self, Cmpop, Expr, Ranged};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::Edit;
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, violation};
@@ -42,14 +43,7 @@ fn get_value_content_for_key_in_dict(
let call = match_call_mut(&mut expression)?;
let attribute = match_attribute(&mut call.func)?;
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
attribute.value.codegen(&mut state);
Ok(state.to_string())
Ok(attribute.value.codegen_stylist(stylist))
}
/// SIM118

View File

@@ -1,7 +1,8 @@
use anyhow::Result;
use libcst_native::{Codegen, CodegenState, CompOp};
use libcst_native::CompOp;
use rustpython_parser::ast::{self, Cmpop, Expr, Ranged, Unaryop};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::source_code::{Locator, Stylist};
@@ -117,13 +118,7 @@ fn reverse_comparison(expr: &Expr, locator: &Locator, stylist: &Stylist) -> Resu
_ => panic!("Expected comparison operator"),
};
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
expression.codegen(&mut state);
Ok(state.to_string())
Ok(expression.codegen_stylist(stylist))
}
/// SIM300

View File

@@ -1,5 +1,5 @@
use anyhow::{anyhow, bail, Ok, Result};
use libcst_native::{Codegen, CodegenState, DictElement, Expression};
use libcst_native::{DictElement, Expression};
use ruff_text_size::TextRange;
use rustpython_format::{
FieldName, FieldNamePart, FieldType, FormatPart, FormatString, FromTemplate,
@@ -7,6 +7,7 @@ use rustpython_format::{
use rustpython_parser::ast::{Excepthandler, Expr, Ranged};
use rustpython_parser::{lexer, Mode, Tok};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::Edit;
use ruff_python_ast::source_code::{Locator, Stylist};
use ruff_python_ast::str::{leading_quote, raw_contents, trailing_quote};
@@ -33,14 +34,10 @@ pub(crate) fn remove_unused_format_arguments_from_dict(
} if raw_contents(name.value).map_or(false, |name| unused_arguments.contains(&name)))
});
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), stmt.range()))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
stmt.range(),
))
}
/// Generate a [`Edit`] to remove unused keyword arguments from a `format` call.
@@ -57,14 +54,10 @@ pub(crate) fn remove_unused_keyword_arguments_from_format_call(
call.args
.retain(|e| !matches!(&e.keyword, Some(kw) if unused_arguments.contains(&kw.value)));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), location))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
location,
))
}
fn unparse_format_part(format_part: FormatPart) -> String {
@@ -193,14 +186,10 @@ pub(crate) fn remove_unused_positional_arguments_from_format_call(
simple_string.value = new_format_string.as_str();
}
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(Edit::range_replacement(state.to_string(), location))
Ok(Edit::range_replacement(
tree.codegen_stylist(stylist),
location,
))
}
/// Generate a [`Edit`] to remove the binding from an exception handler.

View File

@@ -1,9 +1,10 @@
use anyhow::Result;
use libcst_native::{Codegen, CodegenState, ParenthesizableWhitespace};
use libcst_native::ParenthesizableWhitespace;
use ruff_text_size::{TextRange, TextSize};
use rustpython_parser::ast::{Expr, Ranged};
use rustpython_parser::{lexer, Mode, Tok};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::Edit;
use ruff_python_ast::source_code::{Locator, Stylist};
@@ -29,14 +30,7 @@ pub(crate) fn adjust_indentation(
let indented_block = match_indented_block(&mut embedding.body)?;
indented_block.indent = Some(indentation);
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..Default::default()
};
indented_block.codegen(&mut state);
let module_text = state.to_string();
let module_text = indented_block.codegen_stylist(stylist);
let module_text = module_text
.strip_prefix(stylist.line_ending().as_str())
.unwrap()
@@ -61,14 +55,10 @@ pub(crate) fn remove_super_arguments(
body.whitespace_before_args = ParenthesizableWhitespace::default();
body.whitespace_after_func = ParenthesizableWhitespace::default();
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Some(Edit::range_replacement(state.to_string(), range))
Some(Edit::range_replacement(
tree.codegen_stylist(stylist),
range,
))
}
/// Remove any imports matching `members` from an import-from statement.

View File

@@ -1,11 +1,12 @@
use anyhow::Result;
use libcst_native::{
AsName, AssignTargetExpression, Attribute, Codegen, CodegenState, Dot, Expression, Import,
ImportAlias, ImportFrom, ImportNames, Name, NameOrAttribute, ParenthesizableWhitespace,
AsName, AssignTargetExpression, Attribute, Dot, Expression, Import, ImportAlias, ImportFrom,
ImportNames, Name, NameOrAttribute, ParenthesizableWhitespace,
};
use log::error;
use rustpython_parser::ast::{self, Expr, Ranged, Stmt};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::call_path::collect_call_path;
@@ -137,14 +138,7 @@ fn format_import(
} else {
import.names = clean_aliases;
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
let mut content = state.to_string();
let mut content = tree.codegen_stylist(stylist);
content.push_str(&stylist.line_ending());
content.push_str(indent);
content.push_str(&format_mocks(mock_aliases, indent, stylist));
@@ -187,13 +181,7 @@ fn format_import_from(
lpar: vec![],
rpar: vec![],
})));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
Ok(state.to_string())
Ok(tree.codegen_stylist(stylist))
} else if let ImportFrom {
names: ImportNames::Aliases(aliases),
..
@@ -224,14 +212,7 @@ fn format_import_from(
rpar: vec![],
})));
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
tree.codegen(&mut state);
let mut content = state.to_string();
let mut content = tree.codegen_stylist(stylist);
if !mock_aliases.is_empty() {
content.push_str(&stylist.line_ending());
content.push_str(indent);

View File

@@ -1,9 +1,10 @@
use anyhow::{anyhow, bail, Result};
use libcst_native::{Arg, Codegen, CodegenState};
use libcst_native::Arg;
use once_cell::sync::Lazy;
use regex::Regex;
use rustpython_parser::ast::{Expr, Ranged};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::source_code::{Locator, Stylist};
@@ -99,27 +100,16 @@ fn generate_call(
// Fix the string itself.
let item = match_attribute(&mut call.func)?;
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
item.codegen(&mut state);
let cleaned = remove_specifiers(&state.to_string());
let cleaned = remove_specifiers(&item.codegen_stylist(stylist));
call.func = Box::new(match_expression(&cleaned)?);
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
expression.codegen(&mut state);
if module_text == state.to_string() {
let state = expression.codegen_stylist(stylist);
if module_text == state {
// Ex) `'{' '0}'.format(1)`
bail!("Failed to generate call expression for: {module_text}")
}
Ok(state.to_string())
Ok(state)
}
/// UP030

View File

@@ -1,7 +1,7 @@
use anyhow::{bail, Result};
use libcst_native::{Codegen, CodegenState};
use rustpython_parser::ast::{self, Expr, Ranged};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::source_code::{Locator, Stylist};
@@ -77,15 +77,8 @@ fn fix_explicit_f_string_type_conversion(
}
formatted_string_expression.expression = call.args[0].value.clone();
let mut state = CodegenState {
default_newline: &stylist.line_ending(),
default_indent: stylist.indentation(),
..CodegenState::default()
};
expression.codegen(&mut state);
Ok(Fix::automatic(Edit::range_replacement(
state.to_string(),
expression.codegen_stylist(stylist),
range,
)))
}