From 8ac52ad1b069608fc22fd0b5816107057cfdd4e0 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Thu, 2 Jun 2022 13:41:15 +0200 Subject: [PATCH] Fix out of order printing for union/intersection type --- .../src/js/statements/switch_statement.rs | 4 +- .../src/ts/types/intersection_type.rs | 66 +++++++++++-------- .../src/ts/types/union_type.rs | 39 ++++------- 3 files changed, 51 insertions(+), 58 deletions(-) diff --git a/crates/rome_js_formatter/src/js/statements/switch_statement.rs b/crates/rome_js_formatter/src/js/statements/switch_statement.rs index c046b8cddcb..1e4bfda1b18 100644 --- a/crates/rome_js_formatter/src/js/statements/switch_statement.rs +++ b/crates/rome_js_formatter/src/js/statements/switch_statement.rs @@ -16,13 +16,13 @@ impl FormatNodeFields for FormatNodeRule { r_curly_token, } = node.as_fields(); - let format_cases = format_once(|f| { + let format_cases = format_with(|f| { if cases.is_empty() { write!(f, [hard_line_break()])?; } else { let mut join = f.join_nodes_with_hardline(); - for case in cases { + for case in &cases { join.entry(case.syntax(), &case.format()); } diff --git a/crates/rome_js_formatter/src/ts/types/intersection_type.rs b/crates/rome_js_formatter/src/ts/types/intersection_type.rs index d9768e0facc..ded76aa20a3 100644 --- a/crates/rome_js_formatter/src/ts/types/intersection_type.rs +++ b/crates/rome_js_formatter/src/ts/types/intersection_type.rs @@ -1,8 +1,8 @@ use crate::prelude::*; use crate::FormatNodeFields; use rome_formatter::{format_args, write}; -use rome_js_syntax::TsIntersectionType; use rome_js_syntax::TsIntersectionTypeFields; +use rome_js_syntax::{JsSyntaxToken, TsIntersectionType}; impl FormatNodeFields for FormatNodeRule { fn format_fields(node: &TsIntersectionType, f: &mut JsFormatter) -> FormatResult<()> { @@ -11,39 +11,49 @@ impl FormatNodeFields for FormatNodeRule types, } = node.as_fields(); - let leading_separator_token = format_once(|f| { - match leading_separator_token { - Some(token) => { - // The SyntaxToken is converted into a FormatElement using - // Token::from to strip the token's trivia pieces which are - // then reinserted in format_replaced outside of the - // if_group_breaks block to avoid removing comments when the - // group does not break - write!( - f, - [format_replaced( - &token, - &if_group_breaks(format_args!( - format_trimmed_token(&token), - space_token() - )) - )] - ) - } - None => write!( - f, - [if_group_breaks(format_args![token("&"), space_token()])] - ), - } - }); - write!( f, [group_elements(indent(format_args!( soft_line_break(), - leading_separator_token, + FormatTypeSetLeadingSeparator { + separator: "&", + leading_separator: leading_separator_token.as_ref() + }, types.format() )))] ) } } + +pub(crate) struct FormatTypeSetLeadingSeparator<'a> { + pub(crate) separator: &'static str, + pub(crate) leading_separator: Option<&'a JsSyntaxToken>, +} + +impl Format for FormatTypeSetLeadingSeparator<'_> { + fn format(&self, f: &mut JsFormatter) -> FormatResult<()> { + match &self.leading_separator { + Some(token) => { + // The SyntaxToken is converted into a FormatElement using + // Token::from to strip the token's trivia pieces which are + // then reinserted in format_replaced outside of the + // if_group_breaks block to avoid removing comments when the + // group does not break + write!( + f, + [format_replaced( + token, + &if_group_breaks(format_args!(format_trimmed_token(token), space_token())) + )] + ) + } + None => write!( + f, + [if_group_breaks(format_args![ + token(self.separator), + space_token() + ])] + ), + } + } +} diff --git a/crates/rome_js_formatter/src/ts/types/union_type.rs b/crates/rome_js_formatter/src/ts/types/union_type.rs index 9652c5ddfe4..f0f2700fd7b 100644 --- a/crates/rome_js_formatter/src/ts/types/union_type.rs +++ b/crates/rome_js_formatter/src/ts/types/union_type.rs @@ -1,4 +1,5 @@ use crate::prelude::*; +use crate::ts::types::intersection_type::FormatTypeSetLeadingSeparator; use crate::FormatNodeFields; use rome_formatter::{format_args, write, Buffer, VecBuffer}; use rome_js_syntax::TsUnionType; @@ -11,34 +12,17 @@ impl FormatNodeFields for FormatNodeRule { types, } = node.as_fields(); - let format_leading_separator_token = format_once(|f| { - match leading_separator_token { - Some(token) => { - // The SyntaxToken is converted into a FormatElement using - // Token::from to strip the token's trivia pieces which are - // then reinserted in format_replaced outside of the - // if_group_breaks block to avoid removing comments when the - // group does not break - write!( - f, - [format_replaced( - &token, - &if_group_breaks(format_args!( - format_trimmed_token(&token), - space_token() - )) - )] - ) - } - None => write!( - f, - [if_group_breaks(format_args![token("|"), space_token()])] - ), - } - }); - let mut buffer = VecBuffer::new(f.state_mut()); - write!(buffer, [types.format()])?; + write!( + buffer, + [ + FormatTypeSetLeadingSeparator { + separator: "|", + leading_separator: leading_separator_token.as_ref() + }, + types.format() + ] + )?; let types = buffer.into_element(); @@ -51,7 +35,6 @@ impl FormatNodeFields for FormatNodeRule { [ group_elements(indent(format_args![ soft_line_break(), - format_leading_separator_token, format_once(|f| { f.write_element(leading_comments)?; f.write_element(types)