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

Commit

Permalink
feat(rome_js_formatter): Format Arrow Chains
Browse files Browse the repository at this point in the history
This PR adds support for formatting arrow expression chains

```
const x =
	(a): string =>
	(b) =>
	(c) =>
	(d) =>
	(e) =>
		f;
```
  • Loading branch information
Micha Reiser authored and MichaReiser committed Aug 29, 2022
1 parent 1d9d7a0 commit e1078d8
Show file tree
Hide file tree
Showing 15 changed files with 644 additions and 656 deletions.
26 changes: 25 additions & 1 deletion crates/rome_formatter/src/builders.rs
Expand Up @@ -1231,28 +1231,51 @@ pub fn group<Context>(content: &impl Format<Context>) -> Group<Context> {
Group {
content: Argument::new(content),
group_id: None,
should_expand: false,
}
}

#[derive(Copy, Clone)]
pub struct Group<'a, Context> {
content: Argument<'a, Context>,
group_id: Option<GroupId>,
should_expand: bool,
}

impl<Context> Group<'_, Context> {
pub fn with_group_id(mut self, group_id: Option<GroupId>) -> Self {
self.group_id = group_id;
self
}

/// Setting the value to `true` forces the group to expand regardless if it otherwise would fit on the
/// line or contains any hard line breaks.
///
/// It omits the group if `should_expand` is true and instead writes an [FormatElement::ExpandParent] to
/// force any enclosing group to break as well **except** if the group has a group id, in which case the group
/// gets emitted but its first containing element is a [FormatElement::ExpandParent] to force it into expanded mode.
pub fn should_expand(mut self, should_expand: bool) -> Self {
self.should_expand = should_expand;
self
}
}

impl<Context> Format<Context> for Group<'_, Context> {
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
if self.group_id.is_none() && self.should_expand {
write!(f, [expand_parent()])?;
return f.write_fmt(Arguments::from(&self.content));
}

let mut buffer = GroupBuffer::new(f);

buffer.write_fmt(Arguments::from(&self.content))?;
let content = buffer.into_vec();

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

let content = buffer.into_vec();
if content.is_empty() && self.group_id.is_none() {
return Ok(());
}
Expand All @@ -1269,6 +1292,7 @@ impl<Context> std::fmt::Debug for Group<'_, Context> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GroupElements")
.field("group_id", &self.group_id)
.field("should_break", &self.should_expand)
.field("content", &"{{content}}")
.finish()
}
Expand Down
30 changes: 27 additions & 3 deletions crates/rome_js_formatter/src/js/auxiliary/initializer_clause.rs
@@ -1,11 +1,28 @@
use crate::prelude::*;

use rome_formatter::write;
use crate::utils::{with_assignment_layout, AssignmentLikeLayout};
use rome_formatter::{write, FormatRuleWithOptions};
use rome_js_syntax::JsInitializerClause;
use rome_js_syntax::JsInitializerClauseFields;

#[derive(Debug, Clone, Default)]
pub struct FormatJsInitializerClause;
pub struct FormatJsInitializerClause {
assignment_layout: Option<AssignmentLikeLayout>,
}

#[derive(Default, Debug)]
pub struct FormatJsInitializerClauseOptions {
pub(crate) assignment_layout: Option<AssignmentLikeLayout>,
}

impl FormatRuleWithOptions<JsInitializerClause> for FormatJsInitializerClause {
type Options = FormatJsInitializerClauseOptions;

fn with_options(mut self, options: Self::Options) -> Self {
self.assignment_layout = options.assignment_layout;
self
}
}

impl FormatNodeRule<JsInitializerClause> for FormatJsInitializerClause {
fn fmt_fields(&self, node: &JsInitializerClause, f: &mut JsFormatter) -> FormatResult<()> {
Expand All @@ -14,6 +31,13 @@ impl FormatNodeRule<JsInitializerClause> for FormatJsInitializerClause {
expression,
} = node.as_fields();

write![f, [eq_token.format(), space(), expression.format()]]
write![
f,
[
eq_token.format(),
space(),
with_assignment_layout(&expression?, self.assignment_layout)
]
]
}
}

0 comments on commit e1078d8

Please sign in to comment.