Use platform-appropriate newline character for LibCST embedding (#2028)

Closes #2026.
This commit is contained in:
Charlie Marsh 2023-01-20 09:08:04 -05:00 committed by GitHub
parent 8693236f9e
commit fd6dc2a343
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 12 deletions

View File

@ -75,7 +75,7 @@ pub fn nested_if_statements(checker: &mut Checker, stmt: &Stmt) {
Range::new(stmt.location, nested_if.location), Range::new(stmt.location, nested_if.location),
checker.locator, checker.locator,
) { ) {
match fix_if::fix_nested_if_statements(checker.locator, stmt) { match fix_if::fix_nested_if_statements(checker.locator, checker.stylist, stmt) {
Ok(fix) => { Ok(fix) => {
if fix if fix
.content .content

View File

@ -12,7 +12,7 @@ use crate::ast::types::Range;
use crate::ast::whitespace; use crate::ast::whitespace;
use crate::cst::matchers::match_module; use crate::cst::matchers::match_module;
use crate::fix::Fix; use crate::fix::Fix;
use crate::source_code::Locator; use crate::source_code::{Locator, Stylist};
fn parenthesize_and_operand(expr: Expression) -> Expression { fn parenthesize_and_operand(expr: Expression) -> Expression {
match &expr { match &expr {
@ -32,6 +32,7 @@ fn parenthesize_and_operand(expr: Expression) -> Expression {
/// (SIM102) Convert `if a: if b:` to `if a and b:`. /// (SIM102) Convert `if a: if b:` to `if a and b:`.
pub(crate) fn fix_nested_if_statements( pub(crate) fn fix_nested_if_statements(
locator: &Locator, locator: &Locator,
stylist: &Stylist,
stmt: &rustpython_ast::Stmt, stmt: &rustpython_ast::Stmt,
) -> Result<Fix> { ) -> Result<Fix> {
// Infer the indentation of the outer block. // Infer the indentation of the outer block.
@ -62,7 +63,10 @@ pub(crate) fn fix_nested_if_statements(
let module_text = if outer_indent.is_empty() { let module_text = if outer_indent.is_empty() {
module_text module_text
} else { } else {
Cow::Owned(format!("def f():\n{module_text}")) Cow::Owned(format!(
"def f():{}{module_text}",
stylist.line_ending().as_str()
))
}; };
// Parse the CST. // Parse the CST.
@ -113,7 +117,10 @@ pub(crate) fn fix_nested_if_statements(
})); }));
outer_if.body = inner_if.body.clone(); outer_if.body = inner_if.body.clone();
let mut state = CodegenState::default(); let mut state = CodegenState {
default_newline: stylist.line_ending(),
..Default::default()
};
tree.codegen(&mut state); tree.codegen(&mut state);
// Reconstruct and reformat the code. // Reconstruct and reformat the code.
@ -121,7 +128,9 @@ pub(crate) fn fix_nested_if_statements(
let module_text = if outer_indent.is_empty() { let module_text = if outer_indent.is_empty() {
&module_text &module_text
} else { } else {
module_text.strip_prefix("def f():\n").unwrap() module_text
.strip_prefix(&format!("def f():{}", stylist.line_ending().as_str()))
.unwrap()
}; };
let contents = if is_elif { let contents = if is_elif {
module_text.replacen("if", "elif", 1) module_text.replacen("if", "elif", 1)

View File

@ -118,23 +118,38 @@ impl Deref for Indentation {
/// The line ending style used in Python source code. /// The line ending style used in Python source code.
/// See <https://docs.python.org/3/reference/lexical_analysis.html#physical-lines> /// See <https://docs.python.org/3/reference/lexical_analysis.html#physical-lines>
#[derive(Debug, Default, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum LineEnding { pub enum LineEnding {
#[default]
Lf, Lf,
Cr, Cr,
CrLf, CrLf,
} }
impl Default for LineEnding {
fn default() -> Self {
if cfg!(windows) {
LineEnding::CrLf
} else {
LineEnding::Lf
}
}
}
impl LineEnding {
pub fn as_str(&self) -> &'static str {
match self {
LineEnding::CrLf => "\r\n",
LineEnding::Lf => "\n",
LineEnding::Cr => "\r",
}
}
}
impl Deref for LineEnding { impl Deref for LineEnding {
type Target = str; type Target = str;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
match &self { self.as_str()
LineEnding::CrLf => "\r\n",
LineEnding::Lf => "\n",
LineEnding::Cr => "\r",
}
} }
} }