Skip to content

Commit d10c4b8

Browse files
committed
Pass StringKind around rather than StringQuotes in the formatter
1 parent 1b2b849 commit d10c4b8

File tree

9 files changed

+104
-274
lines changed

9 files changed

+104
-274
lines changed

Cargo.lock

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ruff_python_formatter/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ ruff_python_parser = { path = "../ruff_python_parser" }
2525
ruff_text_size = { path = "../ruff_text_size" }
2626

2727
anyhow = { workspace = true }
28-
bitflags = { workspace = true }
2928
clap = { workspace = true }
3029
countme = { workspace = true }
3130
itertools = { workspace = true }
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use ruff_python_ast::BytesLiteral;
2-
use ruff_text_size::Ranged;
32

43
use crate::prelude::*;
5-
use crate::string::{StringNormalizer, StringPart};
4+
use crate::string::StringNormalizer;
65

76
#[derive(Default)]
87
pub struct FormatBytesLiteral;
@@ -13,7 +12,7 @@ impl FormatNodeRule<BytesLiteral> for FormatBytesLiteral {
1312

1413
StringNormalizer::from_context(f.context())
1514
.with_preferred_quote_style(f.options().quote_style())
16-
.normalize(&StringPart::from_source(item.range(), &locator), &locator)
15+
.normalize(item, &locator)
1716
.fmt(f)
1817
}
1918
}

crates/ruff_python_formatter/src/other/f_string.rs

+13-24
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use ruff_formatter::write;
22
use ruff_python_ast::FString;
3+
use ruff_python_parser::StringKind;
34
use ruff_source_file::Locator;
4-
use ruff_text_size::Ranged;
55

66
use crate::prelude::*;
77
use crate::preview::is_f_string_formatting_enabled;
8-
use crate::string::{Quoting, StringNormalizer, StringPart, StringPrefix, StringQuotes};
8+
use crate::string::{Quoting, StringNormalizer, StringQuotes};
99

1010
use super::f_string_element::FormatFStringElement;
1111

@@ -30,16 +30,14 @@ impl Format<PyFormatContext<'_>> for FormatFString<'_> {
3030
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
3131
let locator = f.context().locator();
3232

33-
let string = StringPart::from_source(self.value.range(), &locator);
34-
3533
let normalizer = StringNormalizer::from_context(f.context())
3634
.with_quoting(self.quoting)
3735
.with_preferred_quote_style(f.options().quote_style());
3836

3937
// If f-string formatting is disabled (not in preview), then we will
4038
// fall back to the previous behavior of normalizing the f-string.
4139
if !is_f_string_formatting_enabled(f.context()) {
42-
let result = normalizer.normalize(&string, &locator).fmt(f);
40+
let result = normalizer.normalize(self.value, &locator).fmt(f);
4341
let comments = f.context().comments();
4442
self.value.elements.iter().for_each(|value| {
4543
comments.mark_verbatim_node_comments_formatted(value.into());
@@ -59,16 +57,16 @@ impl Format<PyFormatContext<'_>> for FormatFString<'_> {
5957
return result;
6058
}
6159

62-
let quote_selection = normalizer.choose_quotes(&string, &locator);
60+
let string_kind = normalizer.choose_quotes(self.value, &locator).kind();
6361

6462
let context = FStringContext::new(
65-
string.prefix(),
66-
quote_selection.quotes(),
63+
string_kind,
6764
FStringLayout::from_f_string(self.value, &locator),
6865
);
6966

7067
// Starting prefix and quote
71-
write!(f, [string.prefix(), quote_selection.quotes()])?;
68+
let quotes = StringQuotes::from(string_kind);
69+
write!(f, [string_kind.prefix(), quotes])?;
7270

7371
f.join()
7472
.entries(
@@ -80,32 +78,23 @@ impl Format<PyFormatContext<'_>> for FormatFString<'_> {
8078
.finish()?;
8179

8280
// Ending quote
83-
quote_selection.quotes().fmt(f)
81+
quotes.fmt(f)
8482
}
8583
}
8684

8785
#[derive(Clone, Copy, Debug)]
8886
pub(crate) struct FStringContext {
89-
prefix: StringPrefix,
90-
quotes: StringQuotes,
87+
kind: StringKind,
9188
layout: FStringLayout,
9289
}
9390

9491
impl FStringContext {
95-
const fn new(prefix: StringPrefix, quotes: StringQuotes, layout: FStringLayout) -> Self {
96-
Self {
97-
prefix,
98-
quotes,
99-
layout,
100-
}
101-
}
102-
103-
pub(crate) const fn quotes(self) -> StringQuotes {
104-
self.quotes
92+
const fn new(kind: StringKind, layout: FStringLayout) -> Self {
93+
Self { kind, layout }
10594
}
10695

107-
pub(crate) const fn prefix(self) -> StringPrefix {
108-
self.prefix
96+
pub(crate) fn kind(self) -> StringKind {
97+
self.kind
10998
}
11099

111100
pub(crate) const fn layout(self) -> FStringLayout {

crates/ruff_python_formatter/src/other/f_string_element.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,7 @@ impl<'a> FormatFStringLiteralElement<'a> {
5656
impl Format<PyFormatContext<'_>> for FormatFStringLiteralElement<'_> {
5757
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
5858
let literal_content = f.context().locator().slice(self.element.range());
59-
let normalized = normalize_string(
60-
literal_content,
61-
0,
62-
self.context.quotes(),
63-
self.context.prefix(),
64-
true,
65-
);
59+
let normalized = normalize_string(literal_content, 0, self.context.kind(), true);
6660
match &normalized {
6761
Cow::Borrowed(_) => source_text_slice(self.element.range()).fmt(f),
6862
Cow::Owned(normalized) => text(normalized).fmt(f),

crates/ruff_python_formatter/src/other/string_literal.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use ruff_python_ast::StringLiteral;
2-
use ruff_text_size::Ranged;
32

43
use crate::prelude::*;
5-
use crate::string::{docstring, Quoting, StringNormalizer, StringPart};
4+
use crate::string::{docstring, Quoting, StringNormalizer};
65
use crate::QuoteStyle;
76

87
pub(crate) struct FormatStringLiteral<'a> {
@@ -61,10 +60,7 @@ impl Format<PyFormatContext<'_>> for FormatStringLiteral<'_> {
6160
let normalized = StringNormalizer::from_context(f.context())
6261
.with_quoting(self.layout.quoting())
6362
.with_preferred_quote_style(quote_style)
64-
.normalize(
65-
&StringPart::from_source(self.value.range(), &locator),
66-
&locator,
67-
);
63+
.normalize(self.value, &locator);
6864

6965
if self.layout.is_docstring() {
7066
docstring::format(&normalized, f)

crates/ruff_python_formatter/src/string/docstring.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use {
1818
ruff_text_size::{Ranged, TextLen, TextRange, TextSize},
1919
};
2020

21+
use crate::string::StringQuotes;
2122
use crate::{prelude::*, DocstringCodeLineWidth, FormatModuleError};
2223

2324
use super::NormalizedString;
@@ -126,7 +127,9 @@ pub(crate) fn format(normalized: &NormalizedString, f: &mut PyFormatter) -> Form
126127
let mut lines = docstring.split('\n').peekable();
127128

128129
// Start the string
129-
write!(f, [normalized.prefix(), normalized.quotes()])?;
130+
let kind = normalized.kind();
131+
let quotes = StringQuotes::from(kind);
132+
write!(f, [kind.prefix(), quotes])?;
130133
// We track where in the source docstring we are (in source code byte offsets)
131134
let mut offset = normalized.start();
132135

@@ -142,7 +145,7 @@ pub(crate) fn format(normalized: &NormalizedString, f: &mut PyFormatter) -> Form
142145

143146
// Edge case: The first line is `""" "content`, so we need to insert chaperone space that keep
144147
// inner quotes and closing quotes from getting to close to avoid `""""content`
145-
if trim_both.starts_with(normalized.quotes().quote_char.as_char()) {
148+
if trim_both.starts_with(quotes.quote_char.as_char()) {
146149
space().fmt(f)?;
147150
}
148151

@@ -169,7 +172,7 @@ pub(crate) fn format(normalized: &NormalizedString, f: &mut PyFormatter) -> Form
169172
{
170173
space().fmt(f)?;
171174
}
172-
normalized.quotes().fmt(f)?;
175+
quotes.fmt(f)?;
173176
return Ok(());
174177
}
175178

@@ -195,7 +198,7 @@ pub(crate) fn format(normalized: &NormalizedString, f: &mut PyFormatter) -> Form
195198
offset,
196199
stripped_indentation,
197200
already_normalized,
198-
quote_char: normalized.quotes().quote_char,
201+
quote_char: quotes.quote_char,
199202
code_example: CodeExample::default(),
200203
}
201204
.add_iter(lines)?;
@@ -208,7 +211,7 @@ pub(crate) fn format(normalized: &NormalizedString, f: &mut PyFormatter) -> Form
208211
space().fmt(f)?;
209212
}
210213

211-
write!(f, [normalized.quotes()])
214+
write!(f, [quotes])
212215
}
213216

214217
fn contains_unescaped_newline(haystack: &str) -> bool {
@@ -1570,7 +1573,7 @@ fn docstring_format_source(
15701573
/// that avoids `content""""` and `content\"""`. This does only applies to un-escaped backslashes,
15711574
/// so `content\\ """` doesn't need a space while `content\\\ """` does.
15721575
fn needs_chaperone_space(normalized: &NormalizedString, trim_end: &str) -> bool {
1573-
trim_end.ends_with(normalized.quotes().quote_char.as_char())
1576+
trim_end.ends_with(normalized.kind().quote_style().as_char())
15741577
|| trim_end.chars().rev().take_while(|c| *c == '\\').count() % 2 == 1
15751578
}
15761579

0 commit comments

Comments
 (0)