Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
feature(formatter): Add LineSuffixBoundary IR element
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed May 18, 2022
1 parent 0e4c017 commit cd2bcde
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
29 changes: 29 additions & 0 deletions crates/rome_formatter/src/format_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,29 @@ pub fn line_suffix(element: impl Into<FormatElement>) -> FormatElement {
FormatElement::LineSuffix(Box::new(element.into()))
}

/// Inserts a boundary for line suffixes that forces to print all pending line suffixes. Helpful
/// if a line sufix shouldn't pass a certain point.
///
/// ## Examples
///
/// Forces the line suffix "c" to be printed before the token `d`.
/// ```
/// use rome_formatter::Formatted;
/// use rome_formatter::prelude::*;
///
/// let elements = format_elements![token("a"), line_suffix(token("c")), token("b"), line_suffix_boundary(), token("d")];
///
/// assert_eq!(
/// "abc\nd",
/// Formatted::new(elements, PrinterOptions::default())
/// .print()
/// .as_code()
/// );
/// ```
pub const fn line_suffix_boundary() -> FormatElement {
FormatElement::LineSuffixBoundary
}

/// Mark a [FormatElement] as being a piece of trivia
///
/// This does not directly influence how this content will be printed, but some
Expand Down Expand Up @@ -1079,6 +1102,10 @@ pub enum FormatElement {
/// Delay the printing of its content until the next line break
LineSuffix(Content),

/// Prevents that line suffixes move past this boundary. Forces the printer to print any pending
/// line suffixes, potentially by inserting a hard line break.
LineSuffixBoundary,

/// Special semantic element letting the printer and formatter know this is
/// a trivia content, and it should only have a limited influence on the
/// formatting (for instance line breaks contained within will not cause
Expand Down Expand Up @@ -1163,6 +1190,7 @@ impl Debug for FormatElement {
FormatElement::LineSuffix(content) => {
fmt.debug_tuple("LineSuffix").field(content).finish()
}
FormatElement::LineSuffixBoundary => write!(fmt, "LineSuffixBoundary"),
FormatElement::Comment(content) => fmt.debug_tuple("Comment").field(content).finish(),
FormatElement::Verbatim(verbatim) => fmt
.debug_tuple("Verbatim")
Expand Down Expand Up @@ -1556,6 +1584,7 @@ impl FormatElement {
FormatElement::LineSuffix(_) => false,
FormatElement::Comment(content) => content.will_break(),
FormatElement::Verbatim(verbatim) => verbatim.element.will_break(),
FormatElement::LineSuffixBoundary => false,
}
}

Expand Down
18 changes: 17 additions & 1 deletion crates/rome_formatter/src/printer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::format_element::{
ConditionalGroupContent, Group, LineMode, List, PrintMode, VerbatimKind,
};
use crate::intersperse::Intersperse;
use crate::{FormatElement, GroupId, Printed, SourceMarker, TextRange};
use crate::{hard_line_break, FormatElement, GroupId, Printed, SourceMarker, TextRange};

use crate::prelude::Line;
use rome_rowan::TextSize;
Expand Down Expand Up @@ -221,6 +221,12 @@ impl<'a> Printer<'a> {
.line_suffixes
.push(PrintElementCall::new(&**suffix, args));
}
FormatElement::LineSuffixBoundary => {
const HARD_BREAK: &FormatElement = &hard_line_break();
// enqueue a line break, this will flush the line suffix
queue.enqueue(PrintElementCall::new(HARD_BREAK, args));
}

FormatElement::Comment(content) => {
queue.enqueue(PrintElementCall::new(content.as_ref(), args));
}
Expand Down Expand Up @@ -597,6 +603,7 @@ fn fits_on_line<'a>(
pending_indent: printer.state.pending_indent,
pending_space: printer.state.pending_space,
line_width: printer.state.line_width,
has_line_suffix: printer.state.line_suffixes.is_empty(),
};

let result = loop {
Expand Down Expand Up @@ -743,6 +750,14 @@ fn fits_element_on_line<'a, 'rest>(
if args.mode.is_flat() {
return Fits::No;
}

state.has_line_suffix = true;
}

FormatElement::LineSuffixBoundary => {
if state.has_line_suffix {
return Fits::No;
}
}

FormatElement::Comment(content) => queue.enqueue(PrintElementCall::new(content, args)),
Expand Down Expand Up @@ -779,6 +794,7 @@ impl From<bool> for Fits {
struct MeasureState {
pending_indent: u16,
pending_space: bool,
has_line_suffix: bool,
line_width: usize,
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
assertion_line: 121
expression: while.js

---
# Input
```js
Expand Down

0 comments on commit cd2bcde

Please sign in to comment.