Implement integer literal formatting (#3183)

This commit is contained in:
Charlie Marsh 2023-02-23 13:31:56 -05:00 committed by GitHub
parent 08be7bd285
commit 376eab3a53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 11 deletions

View file

@ -13,6 +13,7 @@ use crate::cst::{
Arguments, Boolop, Cmpop, Comprehension, Expr, ExprKind, Keyword, Operator, Unaryop,
};
use crate::format::helpers::{is_self_closing, is_simple_power, is_simple_slice};
use crate::format::numbers::int_literal;
use crate::format::strings::string_literal;
use crate::shared_traits::AsFormat;
use crate::trivia::{Parenthesize, Relationship, TriviaKind};
@ -652,6 +653,7 @@ fn format_constant(
write!(f, [text("False")])?;
}
}
Constant::Int(_) => write!(f, [int_literal(Range::from_located(expr))])?,
Constant::Str(_) | Constant::Bytes(_) => write!(f, [string_literal(expr)])?,
_ => write!(f, [literal(Range::from_located(expr))])?,
}

View file

@ -8,6 +8,7 @@ mod comprehension;
mod excepthandler;
mod expr;
mod helpers;
mod numbers;
mod operator;
mod stmt;
mod strings;

View file

@ -0,0 +1,53 @@
use ruff_formatter::prelude::*;
use ruff_formatter::{write, Format};
use ruff_text_size::TextSize;
use crate::builders::literal;
use crate::context::ASTFormatContext;
use crate::core::types::Range;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct IntLiteral {
range: Range,
}
impl Format<ASTFormatContext<'_>> for IntLiteral {
fn fmt(&self, f: &mut Formatter<ASTFormatContext<'_>>) -> FormatResult<()> {
let (source, start, end) = f.context().locator().slice(self.range);
for prefix in ["0b", "0B", "0o", "0O", "0x", "0X"] {
if source[start..end].starts_with(prefix) {
// In each case, the prefix must be lowercase, while the suffix must be uppercase.
let prefix = &source[start..start + prefix.len()];
let suffix = &source[start + prefix.len()..end];
if prefix.bytes().any(|b| b.is_ascii_uppercase())
|| suffix.bytes().any(|b| b.is_ascii_lowercase())
{
// Write out the fixed version.
write!(
f,
[
dynamic_text(&prefix.to_lowercase(), TextSize::default()),
dynamic_text(&suffix.to_uppercase(), TextSize::default())
]
)?;
} else {
// Use the existing source.
write!(f, [literal(self.range)])?;
}
return Ok(());
}
}
write!(f, [literal(self.range)])?;
Ok(())
}
}
#[inline]
pub const fn int_literal(range: Range) -> IntLiteral {
IntLiteral { range }
}