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

Commit

Permalink
Some random trash you probably want to undo... Review
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Sep 5, 2022
1 parent 006d9f2 commit 6d0c6e7
Show file tree
Hide file tree
Showing 13 changed files with 322 additions and 437 deletions.
125 changes: 26 additions & 99 deletions crates/rome_formatter/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub trait Buffer {
/// May reserve space for the specified additional elements.
fn reserve(&mut self, _additional: usize);

fn slice(&self) -> &[FormatElement];

/// Glue for usage of the [`write!`] macro with implementors of this trait.
///
/// This method should generally not be invoked manually, but rather through the [`write!`] macro itself.
Expand Down Expand Up @@ -140,6 +142,10 @@ impl<W: Buffer<Context = Context> + ?Sized, Context> Buffer for &mut W {
(**self).reserve(additional)
}

fn slice(&self) -> &[FormatElement] {
(**self).slice()
}

fn write_fmt(&mut self, args: Arguments<Context>) -> FormatResult<()> {
(**self).write_fmt(args)
}
Expand Down Expand Up @@ -225,6 +231,10 @@ impl<Context> Buffer for VecBuffer<'_, Context> {
self.elements.reserve(additional)
}

fn slice(&self) -> &[FormatElement] {
&self
}

fn state(&self) -> &FormatState<Self::Context> {
self.state
}
Expand Down Expand Up @@ -349,6 +359,10 @@ where
self.inner.reserve(additional)
}

fn slice(&self) -> &[FormatElement] {
self.inner.slice()
}

fn state(&self) -> &FormatState<Self::Context> {
self.inner.state()
}
Expand Down Expand Up @@ -404,6 +418,10 @@ where
self.inner.reserve(additional)
}

fn slice(&self) -> &[FormatElement] {
self.inner.slice()
}

fn state(&self) -> &FormatState<Self::Context> {
self.inner.state()
}
Expand Down Expand Up @@ -450,105 +468,6 @@ pub trait BufferExtensions: Buffer + Sized {

Ok(())
}

/// It emits a custom buffer called [WillBreakBuffer], which tracks
/// it he last element written in the main buffer breaks, it does so by
/// checking if their IR emits an [element](FormatElement) that breaks.
///
/// This functionality can be used only one element and only after the element
/// is written in the buffer.
///
/// ## Examples
///
/// ```
/// use rome_formatter::{format, format_args, write, LineWidth};
/// use rome_formatter::prelude::*;
///
/// let formatted = format!(SimpleFormatContext::default(), [format_with(|f| {
///
/// let element = format_with(|f| {
/// write!(f, [
/// text("hello"),
/// hard_line_break(),
/// text("world!")
/// ])
/// });
/// let mut buffer = f.inspect_will_break();
/// write!(buffer, [element])?;
/// let does_element_break = buffer.will_break();
///
/// if does_element_break {
/// write!(f, [hard_line_break(), text("break")])
/// } else {
/// write!(f, [text("did not break")])
/// }
///
/// })]).unwrap();
///
/// assert_eq!(
/// "hello\nworld!\nbreak",
/// formatted.print().as_code()
/// );
/// ```
///
/// ## Alternatives
///
/// Use `Memoized.inspect(f)?.will_break()` if you need to know if some content breaks that should
/// only be written later.
fn inspect_will_break(&mut self) -> WillBreakBuffer<Self::Context> {
WillBreakBuffer::new(self)
}

/// Wraps the current buffer in a [HasLabelBuffer], which tracks
/// labelled elements written in the main buffer, it does so by
/// checking if [element](FormatElement) is a [label](FormatElement::Label)
/// with the expected [label_id](LabelId).
///
/// This functionality can be used only on one element and only after the element
/// is written in the buffer.
///
/// ## Examples
///
/// ```rust
/// use rome_formatter::prelude::*;
/// use rome_formatter::{format, write, LineWidth};
///
/// enum SomeLabelId {}
///
/// let formatted = format!(
/// SimpleFormatContext::default(),
/// [format_with(|f| {
/// let mut buffer = f.inspect_is_labelled::<SomeLabelId>();
///
/// write!(buffer, [
/// labelled(
/// LabelId::of::<SomeLabelId>(),
/// &text("'I have a label'")
/// )
/// ])?;
///
/// let is_labelled = buffer.has_label();
///
/// if is_labelled {
/// write!(f, [text(" has label SomeLabelId")])
/// } else {
/// write!(f, [text(" doesn't have label SomeLabelId")])
/// }
/// })]
/// )
/// .unwrap();
///
/// assert_eq!("'I have a label' has label SomeLabelId", formatted.print().as_code());
/// ```
///
/// /// ## Alternatives
///
/// Use `Memoized.inspect(f)?.has_label(LabelId::of::<SomeLabelId>()` if you need to know if some content breaks that should
/// only be written later.
fn inspect_is_labelled<T: ?Sized + 'static>(&mut self) -> HasLabelBuffer<Self::Context> {
let label_id = LabelId::of::<T>();
HasLabelBuffer::new(self, label_id)
}
}

impl<T> BufferExtensions for T where T: Buffer {}
Expand Down Expand Up @@ -587,6 +506,10 @@ impl<Context> Buffer for HasLabelBuffer<'_, Context> {
self.inner.reserve(additional)
}

fn slice(&self) -> &[FormatElement] {
self.inner.slice()
}

fn state(&self) -> &FormatState<Self::Context> {
self.inner.state()
}
Expand Down Expand Up @@ -645,6 +568,10 @@ impl<Context> Buffer for WillBreakBuffer<'_, Context> {
self.inner.reserve(additional)
}

fn slice(&self) -> &[FormatElement] {
self.inner.slice()
}

fn state(&self) -> &FormatState<Self::Context> {
self.inner.state()
}
Expand Down
118 changes: 55 additions & 63 deletions crates/rome_formatter/src/builders.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use crate::format_element::signal::{Condition, Signal};
use crate::prelude::signal::{DedentMode, LabelId};
use crate::prelude::*;
use crate::Buffer;
use crate::{format_element, Buffer, VecBuffer};
use crate::{
write, Argument, Arguments, BufferSnapshot, FormatState, GroupId, PreambleBuffer, TextRange,
TextSize,
write, Argument, Arguments, BufferSnapshot, FormatState, GroupId, TextRange, TextSize,
};
use rome_rowan::{Language, SyntaxNode, SyntaxToken, SyntaxTokenText, TextLen};
use std::borrow::Cow;
Expand Down Expand Up @@ -1084,29 +1083,22 @@ enum IndentMode {

impl<Context> Format<Context> for BlockIndent<'_, Context> {
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
let mut buffer = PreambleBuffer::new(
f,
format_with(|f| {
f.write_element(FormatElement::Signal(StartIndent))?;

match self.mode {
IndentMode::Soft => write!(f, [soft_line_break()]),
IndentMode::Block => write!(f, [hard_line_break()]),
IndentMode::SoftLineOrSpace => write!(f, [soft_line_break_or_space()]),
}
}),
);
f.write_element(FormatElement::Signal(StartIndent))?;

buffer.write_fmt(Arguments::from(&self.content))?;
match self.mode {
IndentMode::Soft => write!(f, [soft_line_break()]),
IndentMode::Block => write!(f, [hard_line_break()]),
IndentMode::SoftLineOrSpace => write!(f, [soft_line_break_or_space()]),
}?;

if buffer.did_write_preamble() {
f.write_element(FormatElement::Signal(EndIndent))?;
f.write_fmt(Arguments::from(&self.content))?;

match self.mode {
IndentMode::Soft => write!(f, [soft_line_break()])?,
IndentMode::Block => write!(f, [hard_line_break()])?,
IndentMode::SoftLineOrSpace => {}
}
f.write_element(FormatElement::Signal(EndIndent))?;

match self.mode {
IndentMode::Soft => write!(f, [soft_line_break()])?,
IndentMode::Block => write!(f, [hard_line_break()])?,
IndentMode::SoftLineOrSpace => {}
}

Ok(())
Expand Down Expand Up @@ -1234,15 +1226,18 @@ impl<Context> Format<Context> for Group<'_, Context> {
return f.write_fmt(Arguments::from(&self.content));
}

let mut buffer = GroupBuffer::new(f, self.group_id);

buffer.write_fmt(Arguments::from(&self.content))?;
// let mut buffer = GroupBuffer::new(f, self.group_id);
//
// buffer.write_fmt(Arguments::from(&self.content))?;
f.write_element(FormatElement::Signal(Signal::StartGroup(self.group_id)))?;
Arguments::from(&self.content).fmt(f)?;
f.write_element(FormatElement::Signal(Signal::EndGroup))?;

if self.should_expand {
write!(buffer, [expand_parent()])?;
write!(f, [expand_parent()])?;
}

buffer.finish()
Ok(())
}
}

Expand Down Expand Up @@ -1387,6 +1382,10 @@ impl<Context> Buffer for GroupBuffer<'_, Context> {
self.inner.reserve(additional)
}

fn slice(&self) -> &[FormatElement] {
self.inner.slice()
}

fn state(&self) -> &FormatState<Self::Context> {
self.inner.state()
}
Expand Down Expand Up @@ -2080,26 +2079,16 @@ where
/// that appear before the node in the input source.
pub fn entry<L: Language>(&mut self, node: &SyntaxNode<L>, content: &dyn Format<Context>) {
self.result = self.result.and_then(|_| {
let mut buffer = PreambleBuffer::new(
self.fmt,
format_with(|f| {
if self.has_elements {
if get_lines_before(node) > 1 {
write!(f, [empty_line()])?;
} else {
self.separator.fmt(f)?;
}
}

Ok(())
}),
);

write!(buffer, [content])?;

self.has_elements = self.has_elements || buffer.did_write_preamble();
if self.has_elements {
if get_lines_before(node) > 1 {
write!(self.fmt, [empty_line()])?;
} else {
self.separator.fmt(self.fmt)?;
}
}

Ok(())
self.has_elements = true;
write!(self.fmt, [content])
});
}

Expand Down Expand Up @@ -2230,24 +2219,27 @@ impl<'a, Context> BestFitting<'a, Context> {

impl<Context> Format<Context> for BestFitting<'_, Context> {
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
f.write_element(FormatElement::Signal(StartBestFitting))?;

let (last, flat_variants) = self
.variants
.items()
.split_last()
.expect("Best fitting to have at least two variants.");

for variant in flat_variants {
f.write_element(FormatElement::Signal(StartEntry))?;
Arguments::from(variant).fmt(f)?;
f.write_element(FormatElement::Signal(EndEntry))?;
let mut buffer = VecBuffer::new(f.state_mut());
let variants = self.variants.items();

let mut formatted_variants = Vec::with_capacity(variants.len());

for variant in variants {
buffer.write_element(FormatElement::Signal(StartEntry))?;
buffer.write_fmt(Arguments::from(variant))?;
buffer.write_element(FormatElement::Signal(EndEntry))?;

formatted_variants.push(buffer.take_vec().into_boxed_slice());
}

f.write_element(FormatElement::Signal(StartMostExpandedEntry))?;
Arguments::from(last).fmt(f)?;
f.write_element(FormatElement::Signal(EndEntry))?;
// SAFETY: The constructor guarantees that there are always at least two variants. It's, therefore,
// safe to call into the unsafe `from_vec_unchecked` function
let element = unsafe {
FormatElement::BestFitting(format_element::BestFitting::from_vec_unchecked(
formatted_variants,
))
};

f.write_element(FormatElement::Signal(EndBestFitting))
f.write_element(element)
}
}
Loading

0 comments on commit 6d0c6e7

Please sign in to comment.