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

Commit

Permalink
feat(rome_formatter): make formatter language aware (#2629)
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico authored May 31, 2022
1 parent b05b303 commit 9e3aaac
Show file tree
Hide file tree
Showing 420 changed files with 830 additions and 788 deletions.
104 changes: 52 additions & 52 deletions crates/rome_formatter/src/format_extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rome_rowan::SyntaxResult;
/// In order to take advantage of all the functions, you only need to implement the [FormatOptionalTokenAndNode::with_or]
/// function.
pub trait FormatOptional {
type Options;
type Context;

/// This function tries to format an optional object. If the object is [None]
/// an [empty token](crate::FormatElement::Empty) is created. If exists, the utility
Expand All @@ -24,9 +24,9 @@ pub trait FormatOptional {
/// struct MyFormat;
///
/// impl Format for MyFormat {
/// type Options = ();
/// type Context = ();
///
/// fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
/// fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
/// Ok(token("MyToken"))
/// }
/// }
Expand All @@ -46,10 +46,10 @@ pub trait FormatOptional {
fn with_or_empty<With, WithResult>(
&self,
with: With,
) -> FormatWithOr<With, fn() -> FormatElement, WithResult, FormatElement, Self::Options>
) -> FormatWithOr<With, fn() -> FormatElement, WithResult, FormatElement, Self::Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<Self::Options>,
WithResult: IntoFormatElement<Self::Context>,
{
self.with_or(with, empty_element)
}
Expand All @@ -66,8 +66,8 @@ pub trait FormatOptional {
/// struct MyFormat;
///
/// impl Format for MyFormat {
/// type Options = ();
/// fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
/// type Context = ();
/// fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
/// Ok(token("MyToken"))
/// }
/// }
Expand All @@ -77,10 +77,10 @@ pub trait FormatOptional {
/// let result = none_token.or_format(|| token(" other result"));
///
/// assert_eq!(Ok(token(" other result")), formatted![&formatter, [result]]);
fn or_format<Or, OrResult>(&self, op: Or) -> OrFormat<Or, OrResult, Self::Options>
fn or_format<Or, OrResult>(&self, op: Or) -> OrFormat<Or, OrResult, Self::Context>
where
Or: Fn() -> OrResult,
OrResult: IntoFormatElement<Self::Options>,
OrResult: IntoFormatElement<Self::Context>,
{
self.with_or(|token| token, op)
}
Expand All @@ -100,8 +100,8 @@ pub trait FormatOptional {
/// struct MyFormat;
///
/// impl Format for MyFormat {
/// type Options = ();
/// fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
/// type Context = ();
/// fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
/// Ok(token("MyToken"))
/// }
/// }
Expand All @@ -125,12 +125,12 @@ pub trait FormatOptional {
&self,
with: With,
op: Or,
) -> FormatWithOr<With, Or, WithResult, OrResult, Self::Options>
) -> FormatWithOr<With, Or, WithResult, OrResult, Self::Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<Self::Options>,
WithResult: IntoFormatElement<Self::Context>,
Or: Fn() -> OrResult,
OrResult: IntoFormatElement<Self::Options>;
OrResult: IntoFormatElement<Self::Context>;
}

/// Utility trait for formatting a formattable object with some additional content.
Expand All @@ -151,8 +151,8 @@ pub trait FormatWith: Format {
/// struct MyFormat;
///
/// impl Format for MyFormat {
/// type Options = ();
/// fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
/// type Context = ();
/// fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
/// Ok(token("MyToken"))
/// }
/// }
Expand All @@ -164,58 +164,58 @@ pub trait FormatWith: Format {
/// });
///
/// assert_eq!(formatted![&formatter, [token("MyToken"), space_token(), token("+")]], formatted![&formatter, [result]])
fn with<With, WithResult>(&self, with: With) -> FormatItemWith<With, WithResult, Self::Options>
fn with<With, WithResult>(&self, with: With) -> FormatItemWith<With, WithResult, Self::Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<Self::Options>;
WithResult: IntoFormatElement<Self::Context>;
}

pub struct FormatItemWith<'a, With, WithResult, Options>
pub struct FormatItemWith<'a, With, WithResult, Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<Options>,
WithResult: IntoFormatElement<Context>,
{
with: With,
inner: &'a dyn Format<Options = Options>,
inner: &'a dyn Format<Context = Context>,
}

impl<'a, With, WithResult, Options> Format for FormatItemWith<'a, With, WithResult, Options>
impl<'a, With, WithResult, Context> Format for FormatItemWith<'a, With, WithResult, Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<Options>,
WithResult: IntoFormatElement<Context>,
{
type Options = Options;
type Context = Context;

fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
let element = self.inner.format(formatter)?;

(self.with)(element).into_format_element(formatter)
}
}

impl<F: Format> FormatWith for F {
fn with<With, WithResult>(&self, with: With) -> FormatItemWith<With, WithResult, F::Options>
fn with<With, WithResult>(&self, with: With) -> FormatItemWith<With, WithResult, F::Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<F::Options>,
WithResult: IntoFormatElement<F::Context>,
{
FormatItemWith { with, inner: self }
}
}

impl<F: Format> FormatOptional for SyntaxResult<Option<F>> {
type Options = F::Options;
type Context = F::Context;

fn with_or<With, Or, WithResult, OrResult>(
&self,
with: With,
op: Or,
) -> FormatWithOr<With, Or, WithResult, OrResult, Self::Options>
) -> FormatWithOr<With, Or, WithResult, OrResult, Self::Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<Self::Options>,
WithResult: IntoFormatElement<Self::Context>,
Or: Fn() -> OrResult,
OrResult: IntoFormatElement<Self::Options>,
OrResult: IntoFormatElement<Self::Context>,
{
match self {
Err(_) => FormatWithOr::With { inner: self, with },
Expand All @@ -226,18 +226,18 @@ impl<F: Format> FormatOptional for SyntaxResult<Option<F>> {
}

impl<F: Format> FormatOptional for Option<F> {
type Options = F::Options;
type Context = F::Context;

fn with_or<With, Or, WithResult, OrResult>(
&self,
with: With,
op: Or,
) -> FormatWithOr<With, Or, WithResult, OrResult, Self::Options>
) -> FormatWithOr<With, Or, WithResult, OrResult, Self::Context>
where
With: Fn(FormatElement) -> WithResult,
WithResult: IntoFormatElement<Self::Options>,
WithResult: IntoFormatElement<Self::Context>,
Or: Fn() -> OrResult,
OrResult: IntoFormatElement<Self::Options>,
OrResult: IntoFormatElement<Self::Context>,
{
match self {
None => FormatWithOr::Or(op),
Expand All @@ -246,35 +246,35 @@ impl<F: Format> FormatOptional for Option<F> {
}
}

pub type OrFormat<'a, Or, OrResult, Options> =
FormatWithOr<'a, fn(FormatElement) -> FormatElement, Or, FormatElement, OrResult, Options>;
pub type OrFormat<'a, Or, OrResult, Context> =
FormatWithOr<'a, fn(FormatElement) -> FormatElement, Or, FormatElement, OrResult, Context>;

pub enum FormatWithOr<'a, With, Or, WithResult, OrResult, Options>
pub enum FormatWithOr<'a, With, Or, WithResult, OrResult, Context>
where
With: Fn(FormatElement) -> WithResult,
Or: Fn() -> OrResult,
WithResult: IntoFormatElement<Options>,
OrResult: IntoFormatElement<Options>,
WithResult: IntoFormatElement<Context>,
OrResult: IntoFormatElement<Context>,
{
With {
inner: &'a dyn Format<Options = Options>,
inner: &'a dyn Format<Context = Context>,
with: With,
},
Or(Or),
}

impl<'a, With, Or, WithResult, OrResult, Options> Format
for FormatWithOr<'a, With, Or, WithResult, OrResult, Options>
impl<'a, With, Or, WithResult, OrResult, Context> Format
for FormatWithOr<'a, With, Or, WithResult, OrResult, Context>
where
With: Fn(FormatElement) -> WithResult,
Or: Fn() -> OrResult,
WithResult: IntoFormatElement<Options>,
OrResult: IntoFormatElement<Options>,
WithResult: IntoFormatElement<Context>,
OrResult: IntoFormatElement<Context>,
{
type Options = Options;
type Context = Context;

#[inline]
fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
match self {
FormatWithOr::Or(op) => op().into_format_element(formatter),
FormatWithOr::With { inner, with } => {
Expand All @@ -293,7 +293,7 @@ pub trait MemoizeFormat {
///
/// ```
/// use std::cell::Cell;
/// use rome_formatter::FormatOptions;
/// use rome_formatter::FormatContext;
/// use rome_formatter::prelude::*;
/// use rome_rowan::TextSize;
///
Expand All @@ -308,8 +308,8 @@ pub trait MemoizeFormat {
/// }
///
/// impl Format for MyFormat {
/// type Options = ();
/// fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
/// type Context = ();
/// fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
/// let value = self.value.get();
/// self.value.set(value + 1);
///
Expand Down Expand Up @@ -363,9 +363,9 @@ impl<F> Format for Memoized<F>
where
F: Format,
{
type Options = F::Options;
type Context = F::Context;

fn format(&self, formatter: &Formatter<Self::Options>) -> FormatResult<FormatElement> {
fn format(&self, formatter: &Formatter<Self::Context>) -> FormatResult<FormatElement> {
if let Some(memory) = self.memory.borrow().as_ref() {
return memory.clone();
}
Expand Down
19 changes: 10 additions & 9 deletions crates/rome_formatter/src/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,30 @@ use std::cell::RefCell;
/// The formatter is passed to the [Format] implementation of every node in the CST so that they
/// can use it to format their children.
#[derive(Default)]
pub struct Formatter<Options> {
options: Options,
pub struct Formatter<Context> {
/// Yields various information that belong to the current instance of the formatter
context: Context,
group_id_builder: UniqueGroupIdBuilder,
// This is using a RefCell as it only exists in debug mode,
// the Formatter is still completely immutable in release builds
#[cfg(debug_assertions)]
pub printed_tokens: RefCell<PrintedTokens>,
}

impl<Options> Formatter<Options> {
impl<Context> Formatter<Context> {
/// Creates a new context that uses the given formatter options
pub fn new(options: Options) -> Self {
pub fn new(options: Context) -> Self {
Self {
options,
context: options,
group_id_builder: Default::default(),
#[cfg(debug_assertions)]
printed_tokens: Default::default(),
}
}

/// Returns the [FormatOptions] specifying how to format the current CST
pub fn options(&self) -> &Options {
&self.options
pub fn context(&self) -> &Context {
&self.context
}

/// Creates a new group id that is unique to this document. The passed debug name is used in the
Expand Down Expand Up @@ -70,7 +71,7 @@ impl<Options> Formatter<Options> {
///
/// Returns the [Err] of the first item that failed to format.
#[inline]
pub fn format_all<T: Format<Options = Options>>(
pub fn format_all<T: Format<Context = Context>>(
&self,
nodes: impl IntoIterator<Item = T>,
) -> FormatResult<impl Iterator<Item = FormatElement>> {
Expand All @@ -89,7 +90,7 @@ impl<Options> Formatter<Options> {
}
}

impl<Options> Formatter<Options> {
impl<Context> Formatter<Context> {
/// Take a snapshot of the state of the formatter
#[inline]
pub fn snapshot(&self) -> FormatterSnapshot {
Expand Down
Loading

0 comments on commit 9e3aaac

Please sign in to comment.