mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-02 09:52:18 +00:00
Implement float literal formatting (#3184)
This commit is contained in:
parent
376eab3a53
commit
ac79bf4ee9
3 changed files with 125 additions and 13 deletions
|
@ -13,7 +13,7 @@ use crate::cst::{
|
||||||
Arguments, Boolop, Cmpop, Comprehension, Expr, ExprKind, Keyword, Operator, Unaryop,
|
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::helpers::{is_self_closing, is_simple_power, is_simple_slice};
|
||||||
use crate::format::numbers::int_literal;
|
use crate::format::numbers::{float_literal, int_literal};
|
||||||
use crate::format::strings::string_literal;
|
use crate::format::strings::string_literal;
|
||||||
use crate::shared_traits::AsFormat;
|
use crate::shared_traits::AsFormat;
|
||||||
use crate::trivia::{Parenthesize, Relationship, TriviaKind};
|
use crate::trivia::{Parenthesize, Relationship, TriviaKind};
|
||||||
|
@ -654,6 +654,7 @@ fn format_constant(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constant::Int(_) => write!(f, [int_literal(Range::from_located(expr))])?,
|
Constant::Int(_) => write!(f, [int_literal(Range::from_located(expr))])?,
|
||||||
|
Constant::Float(_) => write!(f, [float_literal(Range::from_located(expr))])?,
|
||||||
Constant::Str(_) | Constant::Bytes(_) => write!(f, [string_literal(expr)])?,
|
Constant::Str(_) | Constant::Bytes(_) => write!(f, [string_literal(expr)])?,
|
||||||
_ => write!(f, [literal(Range::from_located(expr))])?,
|
_ => write!(f, [literal(Range::from_located(expr))])?,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,122 @@
|
||||||
use ruff_formatter::prelude::*;
|
use ruff_formatter::prelude::*;
|
||||||
use ruff_formatter::{write, Format};
|
use ruff_formatter::{write, Format};
|
||||||
use ruff_text_size::TextSize;
|
use ruff_text_size::TextSize;
|
||||||
|
use rustpython_parser::ast::Location;
|
||||||
|
|
||||||
use crate::builders::literal;
|
use crate::builders::literal;
|
||||||
use crate::context::ASTFormatContext;
|
use crate::context::ASTFormatContext;
|
||||||
use crate::core::types::Range;
|
use crate::core::types::Range;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
struct FloatAtom {
|
||||||
|
range: Range,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Format<ASTFormatContext<'_>> for FloatAtom {
|
||||||
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext<'_>>) -> FormatResult<()> {
|
||||||
|
let (source, start, end) = f.context().locator().slice(self.range);
|
||||||
|
|
||||||
|
if let Some(dot_index) = source[start..end].find('.') {
|
||||||
|
let integer = &source[start..start + dot_index];
|
||||||
|
let fractional = &source[start + dot_index + 1..end];
|
||||||
|
|
||||||
|
if integer.is_empty() {
|
||||||
|
write!(f, [text("0")])?;
|
||||||
|
} else {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
[literal(Range::new(
|
||||||
|
self.range.location,
|
||||||
|
Location::new(
|
||||||
|
self.range.location.row(),
|
||||||
|
self.range.location.column() + dot_index
|
||||||
|
),
|
||||||
|
))]
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, [text(".")])?;
|
||||||
|
|
||||||
|
if fractional.is_empty() {
|
||||||
|
write!(f, [text("0")])?;
|
||||||
|
} else {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
[literal(Range::new(
|
||||||
|
Location::new(
|
||||||
|
self.range.location.row(),
|
||||||
|
self.range.location.column() + dot_index + 1
|
||||||
|
),
|
||||||
|
self.range.end_location
|
||||||
|
))]
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
write!(f, [literal(self.range)])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn float_atom(range: Range) -> FloatAtom {
|
||||||
|
FloatAtom { range }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
pub struct FloatLiteral {
|
||||||
|
range: Range,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Format<ASTFormatContext<'_>> for FloatLiteral {
|
||||||
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext<'_>>) -> FormatResult<()> {
|
||||||
|
let (source, start, end) = f.context().locator().slice(self.range);
|
||||||
|
|
||||||
|
// Scientific notation
|
||||||
|
if let Some(exponent_index) = source[start..end]
|
||||||
|
.find('e')
|
||||||
|
.or_else(|| source[start..end].find('E'))
|
||||||
|
{
|
||||||
|
// Write the base.
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
[float_atom(Range::new(
|
||||||
|
self.range.location,
|
||||||
|
Location::new(
|
||||||
|
self.range.location.row(),
|
||||||
|
self.range.location.column() + exponent_index
|
||||||
|
),
|
||||||
|
))]
|
||||||
|
)?;
|
||||||
|
|
||||||
|
write!(f, [text("e")])?;
|
||||||
|
|
||||||
|
// Write the exponent, omitting the sign if it's positive.
|
||||||
|
let plus = source[start + exponent_index + 1..end].starts_with('+');
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
[literal(Range::new(
|
||||||
|
Location::new(
|
||||||
|
self.range.location.row(),
|
||||||
|
self.range.location.column() + exponent_index + 1 + usize::from(plus)
|
||||||
|
),
|
||||||
|
self.range.end_location
|
||||||
|
))]
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
write!(f, [float_atom(self.range)])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub const fn float_literal(range: Range) -> FloatLiteral {
|
||||||
|
FloatLiteral { range }
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub struct IntLiteral {
|
pub struct IntLiteral {
|
||||||
range: Range,
|
range: Range,
|
||||||
|
|
|
@ -48,13 +48,13 @@ y = 100(no)
|
||||||
-x = (123456789e123456789).conjugate()
|
-x = (123456789e123456789).conjugate()
|
||||||
-x = 123456789j.real
|
-x = 123456789j.real
|
||||||
-x = 123456789.123456789j.__add__(0b1011.bit_length())
|
-x = 123456789.123456789j.__add__(0b1011.bit_length())
|
||||||
+x = .1.is_integer()
|
+x = 0.1.is_integer()
|
||||||
+x = 1..imag
|
+x = 1.0.imag
|
||||||
+x = 1E+1.imag
|
+x = 1e1.imag
|
||||||
+x = 1E-1.real
|
+x = 1e-1.real
|
||||||
+x = 123456789.123456789.hex()
|
+x = 123456789.123456789.hex()
|
||||||
+x = 123456789.123456789E123456789.real
|
+x = 123456789.123456789e123456789.real
|
||||||
+x = 123456789E123456789.conjugate()
|
+x = 123456789e123456789.conjugate()
|
||||||
+x = 123456789J.real
|
+x = 123456789J.real
|
||||||
+x = 123456789.123456789J.__add__(0b1011.bit_length())
|
+x = 123456789.123456789J.__add__(0b1011.bit_length())
|
||||||
x = 0xB1ACC.conjugate()
|
x = 0xB1ACC.conjugate()
|
||||||
|
@ -79,13 +79,13 @@ y = 100(no)
|
||||||
```py
|
```py
|
||||||
x = 123456789.bit_count()
|
x = 123456789.bit_count()
|
||||||
x = (123456).__abs__()
|
x = (123456).__abs__()
|
||||||
x = .1.is_integer()
|
x = 0.1.is_integer()
|
||||||
x = 1..imag
|
x = 1.0.imag
|
||||||
x = 1E+1.imag
|
x = 1e1.imag
|
||||||
x = 1E-1.real
|
x = 1e-1.real
|
||||||
x = 123456789.123456789.hex()
|
x = 123456789.123456789.hex()
|
||||||
x = 123456789.123456789E123456789.real
|
x = 123456789.123456789e123456789.real
|
||||||
x = 123456789E123456789.conjugate()
|
x = 123456789e123456789.conjugate()
|
||||||
x = 123456789J.real
|
x = 123456789J.real
|
||||||
x = 123456789.123456789J.__add__(0b1011.bit_length())
|
x = 123456789.123456789J.__add__(0b1011.bit_length())
|
||||||
x = 0xB1ACC.conjugate()
|
x = 0xB1ACC.conjugate()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue