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),
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) => {
if fix
.content

View File

@ -12,7 +12,7 @@ use crate::ast::types::Range;
use crate::ast::whitespace;
use crate::cst::matchers::match_module;
use crate::fix::Fix;
use crate::source_code::Locator;
use crate::source_code::{Locator, Stylist};
fn parenthesize_and_operand(expr: Expression) -> Expression {
match &expr {
@ -32,6 +32,7 @@ fn parenthesize_and_operand(expr: Expression) -> Expression {
/// (SIM102) Convert `if a: if b:` to `if a and b:`.
pub(crate) fn fix_nested_if_statements(
locator: &Locator,
stylist: &Stylist,
stmt: &rustpython_ast::Stmt,
) -> Result<Fix> {
// 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() {
module_text
} else {
Cow::Owned(format!("def f():\n{module_text}"))
Cow::Owned(format!(
"def f():{}{module_text}",
stylist.line_ending().as_str()
))
};
// Parse the CST.
@ -113,7 +117,10 @@ pub(crate) fn fix_nested_if_statements(
}));
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);
// Reconstruct and reformat the code.
@ -121,7 +128,9 @@ pub(crate) fn fix_nested_if_statements(
let module_text = if outer_indent.is_empty() {
&module_text
} 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 {
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.
/// See <https://docs.python.org/3/reference/lexical_analysis.html#physical-lines>
#[derive(Debug, Default, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub enum LineEnding {
#[default]
Lf,
Cr,
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 {
type Target = str;
fn deref(&self) -> &Self::Target {
match &self {
LineEnding::CrLf => "\r\n",
LineEnding::Lf => "\n",
LineEnding::Cr => "\r",
}
self.as_str()
}
}