mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-07 09:00:57 +00:00
Split string formatting to individual nodes (#9058)
This PR splits the string formatting code in the formatter to be handled by the respective nodes. Previously, the string formatting was done through a single `FormatString` interface. Now, the nodes themselves are responsible for formatting. The following changes were made: 1. Remove `StringLayout::ImplicitStringConcatenationInBinaryLike` and inline the call to `FormatStringContinuation`. After the refactor, the binary like formatting would delegate to `FormatString` which would then delegate to `FormatStringContinuation`. This removes the intermediary steps. 2. Add formatter implementation for `FStringPart` which delegates it to the respective string literal or f-string node. 3. Add `ExprStringLiteralKind` which is either `String` or `Docstring`. If it's a docstring variant, then the string expression would not be implicitly concatenated. This is guaranteed by the `DocstringStmt::try_from_expression` constructor. 4. Add `StringLiteralKind` which is either a `String`, `Docstring` or `InImplicitlyConcatenatedFString`. The last variant is for when the string literal is implicitly concatenated with an f-string (`"foo" f"bar {x}"`). 5. Remove `FormatString`. 6. Extract the f-string quote detection as a standalone function which is public to the crate. This is used to detect the quote to be used for an f-string at the expression level (`ExprFString` or `FormatStringContinuation`). ### Formatter ecosystem result **This PR** | project | similarity index | total files | changed files | |----------------|------------------:|------------------:|------------------:| | cpython | 0.75804 | 1799 | 1648 | | django | 0.99984 | 2772 | 34 | | home-assistant | 0.99955 | 10596 | 214 | | poetry | 0.99905 | 321 | 15 | | transformers | 0.99967 | 2657 | 324 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99980 | 3669 | 18 | | warehouse | 0.99976 | 654 | 14 | | zulip | 0.99958 | 1459 | 36 | **main** | project | similarity index | total files | changed files | |----------------|------------------:|------------------:|------------------:| | cpython | 0.75804 | 1799 | 1648 | | django | 0.99984 | 2772 | 34 | | home-assistant | 0.99955 | 10596 | 214 | | poetry | 0.99905 | 321 | 15 | | transformers | 0.99967 | 2657 | 324 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99980 | 3669 | 18 | | warehouse | 0.99976 | 654 | 14 | | zulip | 0.99958 | 1459 | 36 |
This commit is contained in:
parent
28b1aa201b
commit
189e947808
17 changed files with 364 additions and 266 deletions
|
@ -2943,70 +2943,6 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
|
|||
}
|
||||
}
|
||||
|
||||
impl FormatRule<ast::FString, PyFormatContext<'_>> for crate::other::f_string::FormatFString {
|
||||
#[inline]
|
||||
fn fmt(&self, node: &ast::FString, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
FormatNodeRule::<ast::FString>::fmt(self, node, f)
|
||||
}
|
||||
}
|
||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::FString {
|
||||
type Format<'a> = FormatRefWithRule<
|
||||
'a,
|
||||
ast::FString,
|
||||
crate::other::f_string::FormatFString,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
fn format(&self) -> Self::Format<'_> {
|
||||
FormatRefWithRule::new(self, crate::other::f_string::FormatFString::default())
|
||||
}
|
||||
}
|
||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::FString {
|
||||
type Format = FormatOwnedWithRule<
|
||||
ast::FString,
|
||||
crate::other::f_string::FormatFString,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
fn into_format(self) -> Self::Format {
|
||||
FormatOwnedWithRule::new(self, crate::other::f_string::FormatFString::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl FormatRule<ast::StringLiteral, PyFormatContext<'_>>
|
||||
for crate::other::string_literal::FormatStringLiteral
|
||||
{
|
||||
#[inline]
|
||||
fn fmt(&self, node: &ast::StringLiteral, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
FormatNodeRule::<ast::StringLiteral>::fmt(self, node, f)
|
||||
}
|
||||
}
|
||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::StringLiteral {
|
||||
type Format<'a> = FormatRefWithRule<
|
||||
'a,
|
||||
ast::StringLiteral,
|
||||
crate::other::string_literal::FormatStringLiteral,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
fn format(&self) -> Self::Format<'_> {
|
||||
FormatRefWithRule::new(
|
||||
self,
|
||||
crate::other::string_literal::FormatStringLiteral::default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::StringLiteral {
|
||||
type Format = FormatOwnedWithRule<
|
||||
ast::StringLiteral,
|
||||
crate::other::string_literal::FormatStringLiteral,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
fn into_format(self) -> Self::Format {
|
||||
FormatOwnedWithRule::new(
|
||||
self,
|
||||
crate::other::string_literal::FormatStringLiteral::default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FormatRule<ast::BytesLiteral, PyFormatContext<'_>>
|
||||
for crate::other::bytes_literal::FormatBytesLiteral
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue