Introduce SourceCodeSlice to reduce the size of FormatElement (#4622)

Introduce `SourceCodeSlice` to reduce the size of `FormatElement`
This commit is contained in:
Micha Reiser 2023-05-24 17:04:52 +02:00 committed by GitHub
parent 6943beee66
commit 86ced3516b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 408 additions and 171 deletions

View file

@ -1,36 +1,34 @@
use std::rc::Rc;
use ruff_formatter::{FormatContext, SimpleFormatOptions};
use ruff_formatter::{FormatContext, SimpleFormatOptions, SourceCode};
use ruff_python_ast::source_code::Locator;
pub struct ASTFormatContext {
#[derive(Clone, Debug)]
pub struct ASTFormatContext<'source> {
options: SimpleFormatOptions,
contents: Rc<str>,
contents: &'source str,
}
impl ASTFormatContext {
pub fn new(options: SimpleFormatOptions, contents: &str) -> Self {
Self {
options,
contents: Rc::from(contents),
}
impl<'source> ASTFormatContext<'source> {
pub fn new(options: SimpleFormatOptions, contents: &'source str) -> Self {
Self { options, contents }
}
pub fn contents(&self) -> &'source str {
self.contents
}
pub fn locator(&self) -> Locator<'source> {
Locator::new(self.contents)
}
}
impl FormatContext for ASTFormatContext {
impl FormatContext for ASTFormatContext<'_> {
type Options = SimpleFormatOptions;
fn options(&self) -> &Self::Options {
&self.options
}
}
impl ASTFormatContext {
pub fn contents(&self) -> Rc<str> {
self.contents.clone()
}
pub fn locator(&self) -> Locator {
Locator::new(&self.contents)
fn source_code(&self) -> SourceCode {
SourceCode::new(self.contents)
}
}

View file

@ -10,7 +10,7 @@ pub struct FormatAlias<'a> {
item: &'a Alias,
}
impl AsFormat<ASTFormatContext> for Alias {
impl AsFormat<ASTFormatContext<'_>> for Alias {
type Format<'a> = FormatAlias<'a>;
fn format(&self) -> Self::Format<'_> {
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Alias {
}
}
impl Format<ASTFormatContext> for FormatAlias<'_> {
impl Format<ASTFormatContext<'_>> for FormatAlias<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let alias = self.item;

View file

@ -10,7 +10,7 @@ pub struct FormatArg<'a> {
item: &'a Arg,
}
impl AsFormat<ASTFormatContext> for Arg {
impl AsFormat<ASTFormatContext<'_>> for Arg {
type Format<'a> = FormatArg<'a>;
fn format(&self) -> Self::Format<'_> {
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Arg {
}
}
impl Format<ASTFormatContext> for FormatArg<'_> {
impl Format<ASTFormatContext<'_>> for FormatArg<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let arg = self.item;

View file

@ -9,7 +9,7 @@ pub struct FormatArguments<'a> {
item: &'a Arguments,
}
impl AsFormat<ASTFormatContext> for Arguments {
impl AsFormat<ASTFormatContext<'_>> for Arguments {
type Format<'a> = FormatArguments<'a>;
fn format(&self) -> Self::Format<'_> {
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for Arguments {
}
}
impl Format<ASTFormatContext> for FormatArguments<'_> {
impl Format<ASTFormatContext<'_>> for FormatArguments<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let args = self.item;

View file

@ -10,7 +10,7 @@ pub struct FormatBoolOp<'a> {
item: &'a BoolOp,
}
impl AsFormat<ASTFormatContext> for BoolOp {
impl AsFormat<ASTFormatContext<'_>> for BoolOp {
type Format<'a> = FormatBoolOp<'a>;
fn format(&self) -> Self::Format<'_> {
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for BoolOp {
}
}
impl Format<ASTFormatContext> for FormatBoolOp<'_> {
impl Format<ASTFormatContext<'_>> for FormatBoolOp<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let bool_op = self.item;
write!(f, [leading_comments(bool_op)])?;

View file

@ -12,7 +12,7 @@ pub(crate) struct Block<'a> {
body: &'a Body,
}
impl Format<ASTFormatContext> for Block<'_> {
impl Format<ASTFormatContext<'_>> for Block<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
for (i, stmt) in self.body.iter().enumerate() {
if i > 0 {
@ -28,7 +28,7 @@ impl Format<ASTFormatContext> for Block<'_> {
write!(f, [empty_line()])?;
}
TriviaKind::OwnLineComment(range) => {
write!(f, [literal(range), hard_line_break()])?;
write!(f, [literal(range, ContainsNewlines::No), hard_line_break()])?;
}
_ => {}
}
@ -49,7 +49,7 @@ pub(crate) struct Statements<'a> {
suite: &'a [Stmt],
}
impl Format<ASTFormatContext> for Statements<'_> {
impl Format<ASTFormatContext<'_>> for Statements<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
for (i, stmt) in self.suite.iter().enumerate() {
if i > 0 {
@ -70,20 +70,18 @@ pub(crate) struct Literal {
range: TextRange,
}
impl Format<ASTFormatContext> for Literal {
impl Format<ASTFormatContext<'_>> for Literal {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let text = f.context().contents();
f.write_element(FormatElement::StaticTextSlice {
text,
range: self.range,
})
source_text_slice(self.range, ContainsNewlines::Detect).fmt(f)
}
}
#[inline]
pub(crate) const fn literal(range: TextRange) -> Literal {
Literal { range }
pub(crate) const fn literal(
range: TextRange,
newlines: ContainsNewlines,
) -> SourceTextSliceBuilder {
source_text_slice(range, newlines)
}
pub(crate) const fn join_names(names: &[String]) -> JoinNames {

View file

@ -10,7 +10,7 @@ pub struct FormatCmpOp<'a> {
item: &'a CmpOp,
}
impl AsFormat<ASTFormatContext> for CmpOp {
impl AsFormat<ASTFormatContext<'_>> for CmpOp {
type Format<'a> = FormatCmpOp<'a>;
fn format(&self) -> Self::Format<'_> {
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for CmpOp {
}
}
impl Format<ASTFormatContext> for FormatCmpOp<'_> {
impl Format<ASTFormatContext<'_>> for FormatCmpOp<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let cmp_op = self.item;
write!(f, [leading_comments(cmp_op)])?;

View file

@ -11,7 +11,7 @@ pub(crate) struct LeadingComments<'a, T> {
item: &'a Attributed<T>,
}
impl<T> Format<ASTFormatContext> for LeadingComments<'_, T> {
impl<T> Format<ASTFormatContext<'_>> for LeadingComments<'_, T> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
for trivia in &self.item.trivia {
if trivia.relationship.is_leading() {
@ -20,7 +20,7 @@ impl<T> Format<ASTFormatContext> for LeadingComments<'_, T> {
write!(f, [empty_line()])?;
}
TriviaKind::OwnLineComment(range) => {
write!(f, [literal(range), hard_line_break()])?;
write!(f, [literal(range, ContainsNewlines::No), hard_line_break()])?;
}
_ => {}
}
@ -40,7 +40,7 @@ pub(crate) struct TrailingComments<'a, T> {
item: &'a Attributed<T>,
}
impl<T> Format<ASTFormatContext> for TrailingComments<'_, T> {
impl<T> Format<ASTFormatContext<'_>> for TrailingComments<'_, T> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
for trivia in &self.item.trivia {
if trivia.relationship.is_trailing() {
@ -49,7 +49,7 @@ impl<T> Format<ASTFormatContext> for TrailingComments<'_, T> {
write!(f, [empty_line()])?;
}
TriviaKind::OwnLineComment(range) => {
write!(f, [literal(range), hard_line_break()])?;
write!(f, [literal(range, ContainsNewlines::No), hard_line_break()])?;
}
_ => {}
}
@ -69,7 +69,7 @@ pub(crate) struct EndOfLineComments<'a, T> {
item: &'a Attributed<T>,
}
impl<T> Format<ASTFormatContext> for EndOfLineComments<'_, T> {
impl<T> Format<ASTFormatContext<'_>> for EndOfLineComments<'_, T> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let mut first = true;
for range in self
@ -81,7 +81,7 @@ impl<T> Format<ASTFormatContext> for EndOfLineComments<'_, T> {
if std::mem::take(&mut first) {
write!(f, [line_suffix(&text(" "))])?;
}
write!(f, [line_suffix(&literal(range))])?;
write!(f, [line_suffix(&literal(range, ContainsNewlines::No))])?;
}
Ok(())
}
@ -97,13 +97,13 @@ pub(crate) struct DanglingComments<'a, T> {
item: &'a Attributed<T>,
}
impl<T> Format<ASTFormatContext> for DanglingComments<'_, T> {
impl<T> Format<ASTFormatContext<'_>> for DanglingComments<'_, T> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
for trivia in &self.item.trivia {
if trivia.relationship.is_dangling() {
if let TriviaKind::OwnLineComment(range) = trivia.kind {
write!(f, [hard_line_break()])?;
write!(f, [literal(range)])?;
write!(f, [literal(range, ContainsNewlines::No)])?;
write!(f, [hard_line_break()])?;
}
}

View file

@ -9,7 +9,7 @@ pub struct FormatComprehension<'a> {
item: &'a Comprehension,
}
impl AsFormat<ASTFormatContext> for Comprehension {
impl AsFormat<ASTFormatContext<'_>> for Comprehension {
type Format<'a> = FormatComprehension<'a>;
fn format(&self) -> Self::Format<'_> {
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for Comprehension {
}
}
impl Format<ASTFormatContext> for FormatComprehension<'_> {
impl Format<ASTFormatContext<'_>> for FormatComprehension<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let comprehension = self.item;

View file

@ -11,7 +11,7 @@ pub struct FormatExcepthandler<'a> {
item: &'a Excepthandler,
}
impl AsFormat<ASTFormatContext> for Excepthandler {
impl AsFormat<ASTFormatContext<'_>> for Excepthandler {
type Format<'a> = FormatExcepthandler<'a>;
fn format(&self) -> Self::Format<'_> {
@ -19,7 +19,7 @@ impl AsFormat<ASTFormatContext> for Excepthandler {
}
}
impl Format<ASTFormatContext> for FormatExcepthandler<'_> {
impl Format<ASTFormatContext<'_>> for FormatExcepthandler<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let excepthandler = self.item;
let ExcepthandlerKind::ExceptHandler { type_, name, body } = &excepthandler.node;

View file

@ -33,7 +33,7 @@ fn format_starred(
}
fn format_name(f: &mut Formatter<ASTFormatContext>, expr: &Expr, _id: &str) -> FormatResult<()> {
write!(f, [literal(expr.range())])?;
write!(f, [literal(expr.range(), ContainsNewlines::No)])?;
write!(f, [end_of_line_comments(expr)])?;
Ok(())
}
@ -57,7 +57,7 @@ fn format_subscript(
if let TriviaKind::OwnLineComment(range) = trivia.kind {
write!(f, [expand_parent()])?;
write!(f, [hard_line_break()])?;
write!(f, [literal(range)])?;
write!(f, [literal(range, ContainsNewlines::No)])?;
}
}
}
@ -573,7 +573,7 @@ fn format_joined_str(
expr: &Expr,
_values: &[Expr],
) -> FormatResult<()> {
write!(f, [literal(expr.range())])?;
write!(f, [literal(expr.range(), ContainsNewlines::Detect)])?;
write!(f, [end_of_line_comments(expr)])?;
Ok(())
}
@ -800,7 +800,7 @@ fn format_if_exp(
Ok(())
}
impl Format<ASTFormatContext> for FormatExpr<'_> {
impl Format<ASTFormatContext<'_>> for FormatExpr<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
if self.item.parentheses.is_always() {
write!(f, [text("(")])?;
@ -871,7 +871,7 @@ impl Format<ASTFormatContext> for FormatExpr<'_> {
if trivia.relationship.is_trailing() {
if let TriviaKind::OwnLineComment(range) = trivia.kind {
write!(f, [expand_parent()])?;
write!(f, [literal(range)])?;
write!(f, [literal(range, ContainsNewlines::No)])?;
write!(f, [hard_line_break()])?;
}
}
@ -885,7 +885,7 @@ impl Format<ASTFormatContext> for FormatExpr<'_> {
}
}
impl AsFormat<ASTFormatContext> for Expr {
impl AsFormat<ASTFormatContext<'_>> for Expr {
type Format<'a> = FormatExpr<'a>;
fn format(&self) -> Self::Format<'_> {

View file

@ -10,7 +10,7 @@ pub struct FormatKeyword<'a> {
item: &'a Keyword,
}
impl AsFormat<ASTFormatContext> for Keyword {
impl AsFormat<ASTFormatContext<'_>> for Keyword {
type Format<'a> = FormatKeyword<'a>;
fn format(&self) -> Self::Format<'_> {
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Keyword {
}
}
impl Format<ASTFormatContext> for FormatKeyword<'_> {
impl Format<ASTFormatContext<'_>> for FormatKeyword<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let keyword = self.item;

View file

@ -11,7 +11,7 @@ pub struct FormatMatchCase<'a> {
item: &'a MatchCase,
}
impl AsFormat<ASTFormatContext> for MatchCase {
impl AsFormat<ASTFormatContext<'_>> for MatchCase {
type Format<'a> = FormatMatchCase<'a>;
fn format(&self) -> Self::Format<'_> {
@ -19,7 +19,7 @@ impl AsFormat<ASTFormatContext> for MatchCase {
}
}
impl Format<ASTFormatContext> for FormatMatchCase<'_> {
impl Format<ASTFormatContext<'_>> for FormatMatchCase<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let MatchCase {
pattern,

View file

@ -12,7 +12,7 @@ struct FloatAtom {
range: TextRange,
}
impl Format<ASTFormatContext> for FloatAtom {
impl Format<ASTFormatContext<'_>> for FloatAtom {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let contents = f.context().contents();
@ -26,12 +26,15 @@ impl Format<ASTFormatContext> for FloatAtom {
} else {
write!(
f,
[literal(TextRange::new(
self.range.start(),
self.range
.start()
.add(TextSize::try_from(dot_index).unwrap())
))]
[literal(
TextRange::new(
self.range.start(),
self.range
.start()
.add(TextSize::try_from(dot_index).unwrap())
),
ContainsNewlines::No
)]
)?;
}
@ -42,16 +45,19 @@ impl Format<ASTFormatContext> for FloatAtom {
} else {
write!(
f,
[literal(TextRange::new(
self.range
.start()
.add(TextSize::try_from(dot_index + 1).unwrap()),
self.range.end()
))]
[literal(
TextRange::new(
self.range
.start()
.add(TextSize::try_from(dot_index + 1).unwrap()),
self.range.end()
),
ContainsNewlines::No
)]
)?;
}
} else {
write!(f, [literal(self.range)])?;
write!(f, [literal(self.range, ContainsNewlines::No)])?;
}
Ok(())
@ -68,7 +74,7 @@ pub(crate) struct FloatLiteral {
range: TextRange,
}
impl Format<ASTFormatContext> for FloatLiteral {
impl Format<ASTFormatContext<'_>> for FloatLiteral {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let contents = f.context().contents();
@ -93,12 +99,15 @@ impl Format<ASTFormatContext> for FloatLiteral {
let plus = content[exponent_index + 1..].starts_with('+');
write!(
f,
[literal(TextRange::new(
self.range
.start()
.add(TextSize::try_from(exponent_index + 1 + usize::from(plus)).unwrap()),
self.range.end()
))]
[literal(
TextRange::new(
self.range.start().add(
TextSize::try_from(exponent_index + 1 + usize::from(plus)).unwrap()
),
self.range.end()
),
ContainsNewlines::No
)]
)?;
} else {
write!(f, [float_atom(self.range)])?;
@ -118,7 +127,7 @@ pub(crate) struct IntLiteral {
range: TextRange,
}
impl Format<ASTFormatContext> for IntLiteral {
impl Format<ASTFormatContext<'_>> for IntLiteral {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let contents = f.context().contents();
@ -142,14 +151,14 @@ impl Format<ASTFormatContext> for IntLiteral {
)?;
} else {
// Use the existing source.
write!(f, [literal(self.range)])?;
write!(f, [literal(self.range, ContainsNewlines::No)])?;
}
return Ok(());
}
}
write!(f, [literal(self.range)])?;
write!(f, [literal(self.range, ContainsNewlines::No)])?;
Ok(())
}
@ -165,20 +174,20 @@ pub(crate) struct ComplexLiteral {
range: TextRange,
}
impl Format<ASTFormatContext> for ComplexLiteral {
impl Format<ASTFormatContext<'_>> for ComplexLiteral {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let contents = f.context().contents();
let content = &contents[self.range];
if content.ends_with('j') {
write!(f, [literal(self.range)])?;
write!(f, [literal(self.range, ContainsNewlines::No)])?;
} else if content.ends_with('J') {
write!(
f,
[literal(TextRange::new(
self.range.start(),
self.range.end().sub(TextSize::from(1))
))]
[literal(
TextRange::new(self.range.start(), self.range.end().sub(TextSize::from(1))),
ContainsNewlines::No
)]
)?;
write!(f, [text("j")])?;
} else {

View file

@ -10,7 +10,7 @@ pub struct FormatOperator<'a> {
item: &'a Operator,
}
impl AsFormat<ASTFormatContext> for Operator {
impl AsFormat<ASTFormatContext<'_>> for Operator {
type Format<'a> = FormatOperator<'a>;
fn format(&self) -> Self::Format<'_> {
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Operator {
}
}
impl Format<ASTFormatContext> for FormatOperator<'_> {
impl Format<ASTFormatContext<'_>> for FormatOperator<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let operator = self.item;
write!(f, [leading_comments(operator)])?;

View file

@ -11,7 +11,7 @@ pub struct FormatPattern<'a> {
item: &'a Pattern,
}
impl AsFormat<ASTFormatContext> for Pattern {
impl AsFormat<ASTFormatContext<'_>> for Pattern {
type Format<'a> = FormatPattern<'a>;
fn format(&self) -> Self::Format<'_> {
@ -19,7 +19,7 @@ impl AsFormat<ASTFormatContext> for Pattern {
}
}
impl Format<ASTFormatContext> for FormatPattern<'_> {
impl Format<ASTFormatContext<'_>> for FormatPattern<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let pattern = self.item;

View file

@ -756,7 +756,7 @@ pub struct FormatStmt<'a> {
item: &'a Stmt,
}
impl Format<ASTFormatContext> for FormatStmt<'_> {
impl Format<ASTFormatContext<'_>> for FormatStmt<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
write!(f, [leading_comments(self.item)])?;
@ -939,7 +939,7 @@ impl Format<ASTFormatContext> for FormatStmt<'_> {
}
}
impl AsFormat<ASTFormatContext> for Stmt {
impl AsFormat<ASTFormatContext<'_>> for Stmt {
type Format<'a> = FormatStmt<'a>;
fn format(&self) -> Self::Format<'_> {

View file

@ -13,7 +13,7 @@ pub(crate) struct StringLiteralPart {
range: TextRange,
}
impl Format<ASTFormatContext> for StringLiteralPart {
impl Format<ASTFormatContext<'_>> for StringLiteralPart {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let contents = f.context().contents();
@ -115,7 +115,7 @@ pub(crate) struct StringLiteral<'a> {
expr: &'a Expr,
}
impl Format<ASTFormatContext> for StringLiteral<'_> {
impl Format<ASTFormatContext<'_>> for StringLiteral<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let expr = self.expr;

View file

@ -9,7 +9,7 @@ pub struct FormatUnaryOp<'a> {
item: &'a UnaryOp,
}
impl AsFormat<ASTFormatContext> for UnaryOp {
impl AsFormat<ASTFormatContext<'_>> for UnaryOp {
type Format<'a> = FormatUnaryOp<'a>;
fn format(&self) -> Self::Format<'_> {
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for UnaryOp {
}
}
impl Format<ASTFormatContext> for FormatUnaryOp<'_> {
impl Format<ASTFormatContext<'_>> for FormatUnaryOp<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let unary_op = self.item;
write!(

View file

@ -9,7 +9,7 @@ pub struct FormatWithitem<'a> {
item: &'a Withitem,
}
impl AsFormat<ASTFormatContext> for Withitem {
impl AsFormat<ASTFormatContext<'_>> for Withitem {
type Format<'a> = FormatWithitem<'a>;
fn format(&self) -> Self::Format<'_> {
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for Withitem {
}
}
impl Format<ASTFormatContext> for FormatWithitem<'_> {
impl Format<ASTFormatContext<'_>> for FormatWithitem<'_> {
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
let withitem = self.item;