Skip to content

Commit

Permalink
Remove mode from best fitting
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Jul 9, 2023
1 parent 537c84f commit fa060af
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 175 deletions.
112 changes: 1 addition & 111 deletions crates/ruff_formatter/src/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2362,7 +2362,6 @@ impl<'a, 'buf, Context> FillBuilder<'a, 'buf, Context> {
#[derive(Copy, Clone)]
pub struct BestFitting<'a, Context> {
variants: Arguments<'a, Context>,
mode: BestFittingMode,
}

impl<'a, Context> BestFitting<'a, Context> {
Expand All @@ -2380,115 +2379,7 @@ impl<'a, Context> BestFitting<'a, Context> {
"Requires at least the least expanded and most expanded variants"
);

Self {
variants,
mode: BestFittingMode::default(),
}
}

/// Changes the mode used by this best fitting element to determine whether a variant fits.
///
/// ## Examples
///
/// ### All Lines
///
/// ```
/// use ruff_formatter::{Formatted, LineWidth, format, format_args, SimpleFormatOptions};
/// use ruff_formatter::prelude::*;
///
/// # fn main() -> FormatResult<()> {
/// let formatted = format!(
/// SimpleFormatContext::default(),
/// [
/// best_fitting!(
/// // Everything fits on a single line
/// format_args!(
/// group(&format_args![
/// text("["),
/// soft_block_indent(&format_args![
/// text("1,"),
/// soft_line_break_or_space(),
/// text("2,"),
/// soft_line_break_or_space(),
/// text("3"),
/// ]),
/// text("]")
/// ]),
/// space(),
/// text("+"),
/// space(),
/// text("aVeryLongIdentifier")
/// ),
///
/// // Breaks after `[` and prints each elements on a single line
/// // The group is necessary because the variant, by default is printed in flat mode and a
/// // hard line break indicates that the content doesn't fit.
/// format_args!(
/// text("["),
/// group(&block_indent(&format_args![text("1,"), hard_line_break(), text("2,"), hard_line_break(), text("3")])).should_expand(true),
/// text("]"),
/// space(),
/// text("+"),
/// space(),
/// text("aVeryLongIdentifier")
/// ),
///
/// // Adds parentheses and indents the body, breaks after the operator
/// format_args!(
/// text("("),
/// block_indent(&format_args![
/// text("["),
/// block_indent(&format_args![
/// text("1,"),
/// hard_line_break(),
/// text("2,"),
/// hard_line_break(),
/// text("3"),
/// ]),
/// text("]"),
/// hard_line_break(),
/// text("+"),
/// space(),
/// text("aVeryLongIdentifier")
/// ]),
/// text(")")
/// )
/// ).with_mode(BestFittingMode::AllLines)
/// ]
/// )?;
///
/// let document = formatted.into_document();
///
/// // Takes the first variant if everything fits on a single line
/// assert_eq!(
/// "[1, 2, 3] + aVeryLongIdentifier",
/// Formatted::new(document.clone(), SimpleFormatContext::default())
/// .print()?
/// .as_code()
/// );
///
/// // It takes the second if the first variant doesn't fit on a single line. The second variant
/// // has some additional line breaks to make sure inner groups don't break
/// assert_eq!(
/// "[\n\t1,\n\t2,\n\t3\n] + aVeryLongIdentifier",
/// Formatted::new(document.clone(), SimpleFormatContext::new(SimpleFormatOptions { line_width: 23.try_into().unwrap(), ..SimpleFormatOptions::default() }))
/// .print()?
/// .as_code()
/// );
///
/// // Prints the last option as last resort
/// assert_eq!(
/// "(\n\t[\n\t\t1,\n\t\t2,\n\t\t3\n\t]\n\t+ aVeryLongIdentifier\n)",
/// Formatted::new(document.clone(), SimpleFormatContext::new(SimpleFormatOptions { line_width: 22.try_into().unwrap(), ..SimpleFormatOptions::default() }))
/// .print()?
/// .as_code()
/// );
/// # Ok(())
/// # }
/// ```
pub fn with_mode(mut self, mode: BestFittingMode) -> Self {
self.mode = mode;
self
Self { variants }
}
}

Expand All @@ -2514,7 +2405,6 @@ impl<Context> Format<Context> for BestFitting<'_, Context> {
variants: format_element::BestFittingVariants::from_vec_unchecked(
formatted_variants,
),
mode: self.mode,
}
};

Expand Down
31 changes: 2 additions & 29 deletions crates/ruff_formatter/src/format_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ pub enum FormatElement {

/// A list of different variants representing the same content. The printer picks the best fitting content.
/// Line breaks inside of a best fitting don't propagate to parent groups.
BestFitting {
variants: BestFittingVariants,
mode: BestFittingMode,
},
BestFitting { variants: BestFittingVariants },

/// A [Tag] that marks the start/end of some content to which some special formatting is applied.
Tag(Tag),
Expand All @@ -87,10 +84,9 @@ impl std::fmt::Debug for FormatElement {
.field(contains_newlines)
.finish(),
FormatElement::LineSuffixBoundary => write!(fmt, "LineSuffixBoundary"),
FormatElement::BestFitting { variants, mode } => fmt
FormatElement::BestFitting { variants } => fmt
.debug_struct("BestFitting")
.field("variants", variants)
.field("mode", &mode)
.finish(),
FormatElement::Interned(interned) => {
fmt.debug_list().entries(interned.deref()).finish()
Expand Down Expand Up @@ -301,29 +297,6 @@ impl FormatElements for FormatElement {
}
}

/// Mode used to determine if any variant (except the most expanded) fits for [`BestFittingVariants`].
#[repr(u8)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
pub enum BestFittingMode {
/// The variant fits if the content up to the first hard or a soft line break inside a [`Group`] with
/// [`PrintMode::Expanded`] fits on the line. The default mode.
///
/// [`Group`]: tag::Group
#[default]
FirstLine,

/// A variant fits if all lines fit into the configured print width. A line ends if by any
/// hard or a soft line break inside a [`Group`] with [`PrintMode::Expanded`].
/// The content doesn't fit if there's any hard line break outside a [`Group`] with [`PrintMode::Expanded`]
/// (a hard line break in content that should be considered in [`PrintMode::Flat`].
///
/// Use this mode with caution as it requires measuring all content of the variant which is more
/// expensive than using [`BestFittingMode::FirstLine`].
///
/// [`Group`]: tag::Group
AllLines,
}

/// The different variants for this element.
/// The first element is the one that takes up the most space horizontally (the most flat),
/// The last element takes up the least space horizontally (but most horizontal space).
Expand Down
14 changes: 2 additions & 12 deletions crates/ruff_formatter/src/format_element/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl Document {
interned_expands
}
},
FormatElement::BestFitting { variants, mode: _ } => {
FormatElement::BestFitting { variants } => {
enclosing.push(Enclosing::BestFitting);

for variant in variants {
Expand Down Expand Up @@ -303,7 +303,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(f, [text("line_suffix_boundary")])?;
}

FormatElement::BestFitting { variants, mode } => {
FormatElement::BestFitting { variants } => {
write!(f, [text("best_fitting([")])?;
f.write_elements([
FormatElement::Tag(StartIndent),
Expand All @@ -319,16 +319,6 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
FormatElement::Line(LineMode::Hard),
])?;

if *mode != BestFittingMode::FirstLine {
write!(
f,
[
dynamic_text(&std::format!("mode: {mode:?},"), None),
space()
]
)?;
}

write!(f, [text("])")])?;
}

Expand Down
31 changes: 8 additions & 23 deletions crates/ruff_formatter/src/printer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod stack;

use crate::format_element::document::Document;
use crate::format_element::tag::{Condition, GroupMode};
use crate::format_element::{BestFittingMode, BestFittingVariants, LineMode, PrintMode};
use crate::format_element::{BestFittingVariants, LineMode, PrintMode};
use crate::prelude::tag;
use crate::prelude::tag::{DedentMode, Tag, TagKind, VerbatimKind};
use crate::printer::call_stack::{
Expand Down Expand Up @@ -135,8 +135,8 @@ impl<'a> Printer<'a> {
self.flush_line_suffixes(queue, stack, Some(HARD_BREAK));
}

FormatElement::BestFitting { variants, mode } => {
self.print_best_fitting(variants, *mode, queue, stack)?;
FormatElement::BestFitting { variants } => {
self.print_best_fitting(variants, queue, stack)?;
}

FormatElement::Interned(content) => {
Expand Down Expand Up @@ -426,7 +426,6 @@ impl<'a> Printer<'a> {
fn print_best_fitting(
&mut self,
variants: &'a BestFittingVariants,
mode: BestFittingMode,
queue: &mut PrintQueue<'a>,
stack: &mut PrintCallStack,
) -> PrintResult<()> {
Expand All @@ -452,9 +451,7 @@ impl<'a> Printer<'a> {
// args must be popped from the stack as soon as it sees the matching end entry.
let content = &variant[1..];

let entry_args = args
.with_print_mode(PrintMode::Flat)
.with_measure_mode(MeasureMode::from(mode));
let entry_args = args.with_print_mode(PrintMode::Flat);

queue.extend_back(content);
stack.push(TagKind::Entry, entry_args);
Expand Down Expand Up @@ -1065,13 +1062,10 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {

FormatElement::SourcePosition(_) => {}

FormatElement::BestFitting { variants, mode } => {
let (slice, args) = match args.mode() {
PrintMode::Flat => (
variants.most_flat(),
args.with_measure_mode(MeasureMode::from(*mode)),
),
PrintMode::Expanded => (variants.most_expanded(), args),
FormatElement::BestFitting { variants } => {
let slice = match args.mode() {
PrintMode::Flat => variants.most_flat(),
PrintMode::Expanded => variants.most_expanded(),
};

if !matches!(slice.first(), Some(FormatElement::Tag(Tag::StartEntry))) {
Expand Down Expand Up @@ -1385,15 +1379,6 @@ enum MeasureMode {
AllLines,
}

impl From<BestFittingMode> for MeasureMode {
fn from(value: BestFittingMode) -> Self {
match value {
BestFittingMode::FirstLine => Self::FirstLine,
BestFittingMode::AllLines => Self::AllLines,
}
}
}

#[cfg(test)]
mod tests {
use crate::prelude::*;
Expand Down

0 comments on commit fa060af

Please sign in to comment.