From 4ac64c0d51a78ebfe52139fe9670fa39ba16928d Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 17 Aug 2022 16:28:16 +0200 Subject: [PATCH 1/3] feat(rome_js_formatter): Format binary expressions --- .../src/js/expressions/binary_expression.rs | 13 +- .../src/js/expressions/in_expression.rs | 13 +- .../js/expressions/instanceof_expression.rs | 13 +- .../src/js/expressions/logical_expression.rs | 23 +- .../expressions/parenthesized_expression.rs | 133 +- .../src/js/expressions/template_element.rs | 6 +- .../src/utils/assignment_like.rs | 8 +- .../src/utils/binary_like_expression.rs | 1574 +++++++++-------- .../src/utils/member_chain/chain_member.rs | 18 +- crates/rome_js_formatter/src/utils/mod.rs | 72 +- crates/rome_js_formatter/src/utils/simple.rs | 229 --- .../specs/js/module/arrow/params.js.snap | 9 +- .../js/module/assignment/assignment.js.snap | 20 +- .../tests/specs/js/module/comments.js.snap | 12 +- .../module/export/expression_clause.js.snap | 2 +- .../expression/binaryish_expression.js.snap | 5 +- .../expression/conditional_expression.js.snap | 2 +- .../expression/logical_expression.js.snap | 90 +- .../object/property_object_member.js.snap | 54 +- .../js/module/parentheses/parentheses.js.snap | 6 +- .../js/assignment-comments/string.js.snap | 51 +- .../prettier/js/assignment/issue-2184.js.snap | 45 - .../prettier/js/babel-plugins/bigint.js.snap | 15 +- .../js/binary-expressions/arrow.js.snap | 75 - .../js/binary-expressions/call.js.snap | 181 -- .../js/binary-expressions/comment.js.snap | 173 -- .../prettier/js/binary-expressions/if.js.snap | 68 - .../js/binary-expressions/inline-jsx.js.snap | 50 +- .../inline-object-array.js.snap | 293 --- .../js/binary-expressions/jsx_parent.js.snap | 54 +- .../js/binary-expressions/return.js.snap | 86 - .../js/binary-expressions/short-right.js.snap | 73 - .../js/binary-expressions/unary.js.snap | 41 - .../prettier/js/binary_math/parens.js.snap | 74 - .../js/bind-expressions/bind_parens.js.snap | 4 +- .../js/class-comment/class-property.js.snap | 47 - .../with_comments.js.snap | 47 - .../prettier/js/classes/property.js.snap | 71 - .../binary-expr.js.snap | 10 +- .../closure-compiler-type-cast.js.snap | 16 +- .../issue-9358.js.snap | 27 +- .../binary-expressions-block-comments.js.snap | 76 +- .../binary-expressions-parens.js.snap | 24 +- .../js/comments/binary-expressions.js.snap | 146 +- .../specs/prettier/js/comments/while.js.snap | 12 +- .../js/function/function_expression.js.snap | 4 +- .../js/logical_expressions/issue-7024.js.snap | 20 +- .../logical_expression_operators.js.snap | 39 +- .../specs/prettier/js/member/logical.js.snap | 43 - .../prettier/js/method-chain/logical.js.snap | 61 +- .../multiparser-css/styled-components.js.snap | 49 +- .../specs/prettier/js/no-semi/no-semi.js.snap | 14 +- .../nullish_coalesing_operator.js.snap | 8 +- .../js/optional-chaining/chaining.js.snap | 57 +- .../js/performance/nested-real.js.snap | 32 +- .../js/preserve-line/member-chain.js.snap | 29 +- .../prettier/js/return/binaryish.js.snap | 109 -- .../specs/prettier/js/spread/spread.js.snap | 41 - .../js/strings/template-literals.js.snap | 235 --- .../specs/prettier/js/switch/switch.js.snap | 133 -- .../sequence-expressions.js.snap | 36 - .../prettier/js/ternaries/binary.js.snap | 40 +- .../prettier/js/ternaries/func-call.js.snap | 14 +- .../js/ternaries/indent-after-paren.js.snap | 104 +- .../prettier/js/ternaries/nested.js.snap | 12 +- .../js/throw_statement/binaryish.js.snap | 109 -- .../js/trailing-whitespace/trailing.js.snap | 56 - .../js/unary-expression/comments.js.snap | 106 +- .../typescript/as/assignment2.ts.snap | 23 +- .../prettier/typescript/as/ternary.ts.snap | 132 -- .../functionImplementationErrors.ts.snap | 201 --- .../functions/functionImplementations.ts.snap | 393 ---- .../template-literals/as-expression.ts.snap | 58 - .../typescript/ternaries/indent.ts.snap | 39 +- .../typescript/webhost/webtsc.ts.snap | 23 +- 75 files changed, 1384 insertions(+), 4897 deletions(-) delete mode 100644 crates/rome_js_formatter/src/utils/simple.rs delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/assignment/issue-2184.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/arrow.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/call.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/comment.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/if.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-object-array.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/return.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/short-right.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/unary.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/binary_math/parens.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/class-comment/class-property.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/classes-private-fields/with_comments.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/classes/property.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/member/logical.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/return/binaryish.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/spread/spread.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/strings/template-literals.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/switch/switch.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/template-literals/sequence-expressions.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/throw_statement/binaryish.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/trailing-whitespace/trailing.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/as/ternary.ts.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementationErrors.ts.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementations.ts.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/template-literals/as-expression.ts.snap diff --git a/crates/rome_js_formatter/src/js/expressions/binary_expression.rs b/crates/rome_js_formatter/src/js/expressions/binary_expression.rs index 56f3e79d233..3a8d952d2b1 100644 --- a/crates/rome_js_formatter/src/js/expressions/binary_expression.rs +++ b/crates/rome_js_formatter/src/js/expressions/binary_expression.rs @@ -1,7 +1,5 @@ use crate::prelude::*; -use crate::utils::{ - format_binary_like_expression, needs_binary_like_parentheses, JsAnyBinaryLikeExpression, -}; +use crate::utils::{needs_binary_like_parentheses, JsAnyBinaryLikeExpression}; use crate::parentheses::{ExpressionNode, NeedsParentheses}; use rome_js_syntax::{JsAnyExpression, JsBinaryExpression, JsSyntaxNode}; @@ -15,10 +13,11 @@ impl FormatNodeRule for FormatJsBinaryExpression { node: &JsBinaryExpression, formatter: &mut JsFormatter, ) -> FormatResult<()> { - format_binary_like_expression( - JsAnyBinaryLikeExpression::JsBinaryExpression(node.clone()), - formatter, - ) + JsAnyBinaryLikeExpression::JsBinaryExpression(node.clone()).fmt(formatter) + } + + fn needs_parentheses(&self, item: &JsBinaryExpression) -> bool { + item.needs_parentheses() } } diff --git a/crates/rome_js_formatter/src/js/expressions/in_expression.rs b/crates/rome_js_formatter/src/js/expressions/in_expression.rs index 381443ad447..2403ec5e9da 100644 --- a/crates/rome_js_formatter/src/js/expressions/in_expression.rs +++ b/crates/rome_js_formatter/src/js/expressions/in_expression.rs @@ -1,7 +1,5 @@ use crate::prelude::*; -use crate::utils::{ - format_binary_like_expression, needs_binary_like_parentheses, JsAnyBinaryLikeExpression, -}; +use crate::utils::{needs_binary_like_parentheses, JsAnyBinaryLikeExpression}; use crate::parentheses::{ExpressionNode, NeedsParentheses}; @@ -15,10 +13,11 @@ pub struct FormatJsInExpression; impl FormatNodeRule for FormatJsInExpression { fn fmt_fields(&self, node: &JsInExpression, formatter: &mut JsFormatter) -> FormatResult<()> { - format_binary_like_expression( - JsAnyBinaryLikeExpression::JsInExpression(node.clone()), - formatter, - ) + JsAnyBinaryLikeExpression::JsInExpression(node.clone()).fmt(formatter) + } + + fn needs_parentheses(&self, item: &JsInExpression) -> bool { + item.needs_parentheses() } } diff --git a/crates/rome_js_formatter/src/js/expressions/instanceof_expression.rs b/crates/rome_js_formatter/src/js/expressions/instanceof_expression.rs index 76dfdf1de58..1d55c34968d 100644 --- a/crates/rome_js_formatter/src/js/expressions/instanceof_expression.rs +++ b/crates/rome_js_formatter/src/js/expressions/instanceof_expression.rs @@ -1,7 +1,5 @@ use crate::prelude::*; -use crate::utils::{ - format_binary_like_expression, needs_binary_like_parentheses, JsAnyBinaryLikeExpression, -}; +use crate::utils::{needs_binary_like_parentheses, JsAnyBinaryLikeExpression}; use crate::parentheses::{ExpressionNode, NeedsParentheses}; use rome_js_syntax::{JsAnyExpression, JsInstanceofExpression, JsSyntaxNode}; @@ -15,10 +13,11 @@ impl FormatNodeRule for FormatJsInstanceofExpression { node: &JsInstanceofExpression, formatter: &mut JsFormatter, ) -> FormatResult<()> { - format_binary_like_expression( - JsAnyBinaryLikeExpression::JsInstanceofExpression(node.clone()), - formatter, - ) + JsAnyBinaryLikeExpression::JsInstanceofExpression(node.clone()).fmt(formatter) + } + + fn needs_parentheses(&self, item: &JsInstanceofExpression) -> bool { + item.needs_parentheses() } } diff --git a/crates/rome_js_formatter/src/js/expressions/logical_expression.rs b/crates/rome_js_formatter/src/js/expressions/logical_expression.rs index a3184d00653..2eaa000bd51 100644 --- a/crates/rome_js_formatter/src/js/expressions/logical_expression.rs +++ b/crates/rome_js_formatter/src/js/expressions/logical_expression.rs @@ -1,10 +1,9 @@ use crate::prelude::*; -use crate::utils::{ - format_binary_like_expression, needs_binary_like_parentheses, JsAnyBinaryLikeExpression, -}; +use crate::utils::{needs_binary_like_parentheses, JsAnyBinaryLikeExpression}; use crate::parentheses::{ExpressionNode, NeedsParentheses}; use rome_js_syntax::{JsAnyExpression, JsLogicalExpression, JsSyntaxNode}; +use rome_rowan::AstNode; #[derive(Debug, Clone, Default)] pub struct FormatJsLogicalExpression; @@ -15,17 +14,25 @@ impl FormatNodeRule for FormatJsLogicalExpression { node: &JsLogicalExpression, formatter: &mut JsFormatter, ) -> FormatResult<()> { - format_binary_like_expression( - JsAnyBinaryLikeExpression::JsLogicalExpression(node.clone()), - formatter, - ) + JsAnyBinaryLikeExpression::JsLogicalExpression(node.clone()).fmt(formatter) + } + + fn needs_parentheses(&self, item: &JsLogicalExpression) -> bool { + item.needs_parentheses() } } impl NeedsParentheses for JsLogicalExpression { fn needs_parentheses_with_parent(&self, parent: &JsSyntaxNode) -> bool { if let Some(parent) = JsLogicalExpression::cast(parent.clone()) { - return parent.operator() != self.operator(); + return if parent.operator() != self.operator() { + true + } else { + // TODO: Parentheses should never be needed for the same operators BUT this is causing a re-formatting + // issue if a logical expression has an in-balanced tree. See issue-7024.js for a test case.. + // The way prettier solves this is by re-balancing the tree before formatting, something, Rome' doesn't yet support. + Ok(self.syntax()) != parent.left().map(AstNode::into_syntax).as_ref() + }; } needs_binary_like_parentheses(&JsAnyBinaryLikeExpression::from(self.clone()), parent) diff --git a/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs b/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs index ca0bf10e70c..e28cfa46697 100644 --- a/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs +++ b/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs @@ -1,18 +1,10 @@ use crate::prelude::*; -use crate::utils::{ - binary_argument_needs_parens, is_simple_expression, FormatPrecedence, - JsAnyBinaryLikeLeftExpression, -}; use rome_formatter::write; -use crate::utils::JsAnyBinaryLikeExpression; - use crate::parentheses::{ExpressionNode, NeedsParentheses}; use rome_js_syntax::{ - JsAnyExpression, JsParenthesizedExpression, JsParenthesizedExpressionFields, JsSyntaxKind, - JsSyntaxNode, + JsAnyExpression, JsParenthesizedExpression, JsParenthesizedExpressionFields, JsSyntaxNode, }; -use rome_rowan::{AstNode, SyntaxResult}; #[derive(Debug, Clone, Default)] pub struct FormatJsParenthesizedExpression; @@ -31,46 +23,14 @@ impl FormatNodeRule for FormatJsParenthesizedExpressi let expression = expression?; - if is_expression_handling_parens(&expression) { - return write!( - f, - [ - format_removed(&l_paren_token?), - expression.format(), - format_removed(&r_paren_token?) - ] - ); - } - - let parenthesis_can_be_omitted = parenthesis_can_be_omitted(node, &expression)?; - - if parenthesis_can_be_omitted { - write![ - f, - [ - format_removed(&l_paren_token?), - expression.format(), - format_removed(&r_paren_token?), - ] + return write!( + f, + [ + format_removed(&l_paren_token?), + expression.format(), + format_removed(&r_paren_token?) ] - } else if is_simple_parenthesized_expression(node)? { - write![ - f, - [ - l_paren_token.format(), - expression.format(), - r_paren_token.format() - ] - ] - } else { - write![ - f, - [ - format_delimited(&l_paren_token?, &expression.format(), &r_paren_token?,) - .soft_block_indent() - ] - ] - } + ); } fn needs_parentheses(&self, item: &JsParenthesizedExpression) -> bool { @@ -78,83 +38,6 @@ impl FormatNodeRule for FormatJsParenthesizedExpressi } } -fn is_simple_parenthesized_expression(node: &JsParenthesizedExpression) -> SyntaxResult { - let JsParenthesizedExpressionFields { - l_paren_token, - expression, - r_paren_token, - } = node.as_fields(); - - if l_paren_token?.has_trailing_comments() || r_paren_token?.has_leading_comments() { - return Ok(false); - } - - if !is_simple_expression(&expression?)? { - return Ok(false); - } - - Ok(true) -} - -// Allow list of nodes that use the new `need_parens` formatting to determine if parentheses are necessary or not. -pub(crate) fn is_expression_handling_parens(expression: &JsAnyExpression) -> bool { - use JsAnyExpression::*; - - if let JsAnyExpression::JsParenthesizedExpression(inner) = expression { - if let Ok(inner) = inner.expression() { - is_expression_handling_parens(&inner) - } else { - false - } - } else { - !matches!( - expression, - JsInstanceofExpression(_) - | JsBinaryExpression(_) - | JsInExpression(_) - | JsLogicalExpression(_) - ) - } -} - -fn parenthesis_can_be_omitted( - node: &JsParenthesizedExpression, - expression: &JsAnyExpression, -) -> SyntaxResult { - let parent = node.syntax().parent(); - - if let Some(parent) = &parent { - match parent.kind() { - // The formatting of the return or throw argument takes care of adding parentheses if necessary - JsSyntaxKind::JS_RETURN_STATEMENT | JsSyntaxKind::JS_THROW_STATEMENT => { - return Ok(true) - } - JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION => return Ok(true), - _ => { - // fall through - } - } - } - - let expression = expression.resolve(); - - let parent_precedence = FormatPrecedence::with_precedence_for_parenthesis(parent.as_ref()); - - if parent_precedence > FormatPrecedence::Low { - return Ok(false); - } - - if let Some(parent) = parent { - if JsAnyBinaryLikeExpression::can_cast(parent.kind()) - && !binary_argument_needs_parens(&JsAnyBinaryLikeLeftExpression::from(expression)) - { - return Ok(true); - } - } - - Ok(false) -} - impl NeedsParentheses for JsParenthesizedExpression { #[inline(always)] fn needs_parentheses(&self) -> bool { diff --git a/crates/rome_js_formatter/src/js/expressions/template_element.rs b/crates/rome_js_formatter/src/js/expressions/template_element.rs index 683ba0049d3..75c63c646b4 100644 --- a/crates/rome_js_formatter/src/js/expressions/template_element.rs +++ b/crates/rome_js_formatter/src/js/expressions/template_element.rs @@ -4,6 +4,7 @@ use rome_formatter::{format_args, write, FormatContext, FormatRuleWithOptions, V use crate::context::TabWidth; use crate::js::lists::template_element_list::{TemplateElementIndention, TemplateElementLayout}; +use crate::parentheses::ExpressionNode; use rome_js_syntax::{ JsAnyExpression, JsSyntaxNode, JsSyntaxToken, JsTemplateElement, TsTemplateElement, }; @@ -106,7 +107,10 @@ impl Format for FormatTemplateElement { TemplateElementLayout::Fit => { use JsAnyExpression::*; - let expression = self.element.expression(); + let expression = self + .element + .expression() + .map(|expression| expression.resolve()); // It's preferred to break after/before `${` and `}` rather than breaking in the // middle of some expressions. diff --git a/crates/rome_js_formatter/src/utils/assignment_like.rs b/crates/rome_js_formatter/src/utils/assignment_like.rs index b58989a4121..4e07d0caaba 100644 --- a/crates/rome_js_formatter/src/utils/assignment_like.rs +++ b/crates/rome_js_formatter/src/utils/assignment_like.rs @@ -848,14 +848,16 @@ pub(crate) fn should_break_after_operator(right: &JsAnyExpression) -> SyntaxResu right if JsAnyBinaryLikeExpression::can_cast(right.syntax().kind()) => { let binary_like = JsAnyBinaryLikeExpression::unwrap_cast(right.syntax().clone()); - !binary_like.should_inline() + !binary_like.should_inline_logical_expression() } JsAnyExpression::JsSequenceExpression(_) => true, JsAnyExpression::JsConditionalExpression(conditional) => { - JsAnyBinaryLikeExpression::cast(conditional.test()?.into_syntax()) - .map_or(false, |expression| !expression.should_inline()) + JsAnyBinaryLikeExpression::cast(conditional.test()?.into_resolved_syntax()) + .map_or(false, |expression| { + !expression.should_inline_logical_expression() + }) } _ => false, diff --git a/crates/rome_js_formatter/src/utils/binary_like_expression.rs b/crates/rome_js_formatter/src/utils/binary_like_expression.rs index ddb855b377d..05a2d253233 100644 --- a/crates/rome_js_formatter/src/utils/binary_like_expression.rs +++ b/crates/rome_js_formatter/src/utils/binary_like_expression.rs @@ -1,716 +1,462 @@ +//! This module implements the formatting of binary like nodes. Binary like nodes are nodes with +//! `left` and `right` expressions. Today, this includes: +//! * [JsBinaryExpression] +//! * [JsLogicalExpression] +//! * [JsInExpression] +//! * [JsInstanceofExpression] +//! +//! The challenge of formatting binary like expressions is that we want to format binary expression +//! chains, when possible, together but they are represented as a deep structured tree in the CST. +//! +//! For example, +//! +//! ```js +//! some && thing && elsewhere || happy +//! ``` +//! +//! Is parsed as +//! +//! ```block +//! JsLogicalExpression { +//! left: JsLogicalExpression { +//! left: JsLogicalExpression { +//! left: "some" +//! operator: "&&", +//! right: "thing" +//! } +//! operator: "&&" +//! right: "elsewhere" +//! } +//! operator: "||" +//! right: "happy" +//! } +//! ``` +//! +//! The goal is to format all the left and right sides together that don't require parentheses (mainly comes down to whether the parent and its left side's operator have the same precedence). +//! +//! This is achieved by traversing down the left side of a binary expression until it reaches the first expression that can't be flattened. +//! For `some && thing && elsewhere || happy`, the implementation checks if the first left-side `some && thing && elsewhere` can be grouped. +//! This isn't the case because the left side operator `&&` differs from the parent's `||` operator. +//! +//! That means, we found the end of the first `group` and the left-side of the group is `some && thing && elsewhere`. +//! The algorithm traverses upwards and adds all right-sides of the parent binary like expressions to the group until it reaches the root. +//! In the example, this only is the `|| happy`. +//! +//! Thus, the first group is: `[Left(some && thing && elsewhere), Right(|| happy)]`. The formatting formats the left side +//! as is (the call will recurse into the [JsAnyBinaryLikeExpression] formatting again) but formats the operator with the right side. +//! +//! Now, let's see how the implementation groups the `some && thing && elsewhere`. It first traverses to the left most binary like expression, +//! which is `some && thing`. It then adds this as a `Left` side to the group. From here, the algorithm traverses upwards and adds all right sides +//! of the binary expression. These are: `&& thing` and `&& elsewhere`. +//! The complete group is: `[Left(some), Right(&& thing), Right(&& elsewhere)]`. +//! +//! Each side in the group gets formatted in order, starting with the left, then formatting the operator +//! and right side of each Right side. + use crate::prelude::*; -use rome_formatter::{write, Buffer, CstFormatContext}; +use rome_formatter::{format_args, write, Buffer, CommentStyle, CstFormatContext}; use rome_js_syntax::{ - JsAnyExpression, JsAnyInProperty, JsBinaryExpression, JsBinaryOperator, JsInExpression, - JsInstanceofExpression, JsLogicalExpression, JsLogicalOperator, JsPrivateName, JsSyntaxKind, - JsSyntaxNode, JsSyntaxToken, OperatorPrecedence, + JsAnyExpression, JsAnyFunctionBody, JsAnyInProperty, JsArrowFunctionExpression, + JsBinaryExpression, JsBinaryOperator, JsDoWhileStatement, JsIfStatement, JsInExpression, + JsInstanceofExpression, JsLogicalExpression, JsLogicalOperator, JsParenthesizedExpression, + JsPrivateName, JsSwitchStatement, JsSyntaxKind, JsSyntaxNode, JsSyntaxToken, JsUnaryExpression, + JsWhileStatement, OperatorPrecedence, }; use crate::parentheses::{ - is_callee, is_member_object, is_spread, is_tag, ExpressionNode, NeedsParentheses, + is_callee, is_member_object, is_spread, is_tag, resolve_parent, ExpressionNode, + NeedsParentheses, }; -use crate::utils::should_break_after_operator; + +use crate::context::JsCommentStyle; +use crate::js::expressions::static_member_expression::JsAnyStaticMemberLike; +use crate::utils::assignment_like::has_leading_own_line_comment; use rome_rowan::{declare_node_union, AstNode, SyntaxResult}; use std::fmt::Debug; +use std::hash::Hash; use std::iter::FusedIterator; -use std::ops::Deref; - -/// This function is charge to flat binaryish expressions that have the same precedence of their operators -/// -/// This means that expressions like `some && thing && elsewhere` are entitled to fall in the same group. -/// -/// Instead, if we encounter something like `some && thing || elsewhere && thing`, we will creat two groups: -/// `[some, thing]` and `[elsewhere, thing]`, each group will be grouped together. -/// -/// -/// Let's take for example: -/// -/// ```js -/// some && thing && elsewhere && happy -/// ``` -/// -/// These expressions have nested nodes, which is roughly something like this: -/// -/// ```block -/// JsLogicalExpression { -/// left: JsLogicalExpression { -/// left: JsLogicalExpression { -/// left: "some" -/// operator: "&&", -/// right: "thing" -/// } -/// operator: "&&" -/// right: "elsewhere" -/// } -/// operator: "&&" -/// right: "happy" -/// } -/// ``` -/// -/// Our final result should be something like this: -/// ```js -/// some && -/// thing && -/// elsewhere && -/// happy -/// ``` -/// -/// So what we are going to do here is: -/// - create a vector of flatten items, where the most nested node is the first one,`left: "some"` in our -/// example. The last one will be the first that we encounter, in this case the node that contains `right: "happy"` -/// - each element of the vector will contain two elements. One is the AST node, the other one is its -/// formatted version -/// - the formatted elements will be grouped -/// -/// -/// The flattening of the groups is done by traversing the binary like expression in post-order, first visiting the left most binary like expression: -/// - not printing nodes/token twice -/// - not "forget" tokens/nodes -/// - apply recursions as long as we encounter the same operator -/// -/// By looking at the formatting, we want to make sure that the operator is always attached to the -/// "left" part of the expression, which means that the last "right" wont' have any operator. -/// -/// In order to achieve that, we basically carry with us the operator of the previous node. -/// -/// Let's try to understand it by checking the example again. The first time we attempt to create a -/// flatten item is when we encounter: `some && thing`, which is a `JsLogicalExpression`. -/// Nothing fancy here. Although, if we needed to format this node, you would notice that we don't have -/// a second operator, because our end result should be: -/// -/// ```js -/// some && -/// thing && -/// ``` -/// -/// So what we do is to "borrow" (no Rust reference) the operator "&&" that belongs to the "parent" - -/// or, if want to see it from a recursion point of view, the previous node that we visited - -/// in our case `elsewhere &&`. We then take its operator token and pass it down. -/// -/// Eventually we will have a `[ JsLogicalExpression, operator2: "&&" ]`. -/// -/// With these elements, we can now create two formatted elements: -/// - `[left, operator: "&&" ]` -/// - `[right, operator2: "&&" ]` -/// -/// Now let's continue until we arrive to the last node that we want to try to format, which is: -/// `&& happy`. If we follow the logic explained so far, this node doesn't have an operator -/// anymore because we passed it to its child. And we can't try to add a new operator. -/// But this is fine! Because this is want we wanted! By removing the operator, we are left with `happy` -/// which is what we wanted since the beginning! -pub(crate) fn format_binary_like_expression( - expression: JsAnyBinaryLikeExpression, - f: &mut JsFormatter, -) -> FormatResult<()> { - let mut flatten_items = FlattenItems::default(); - let current_node = expression.clone(); - - let post_order_binary_like_expressions = PostorderIterator::new(expression); - let mut left: Option = None; - - for parent in post_order_binary_like_expressions { - let parent_operator = parent.operator_token()?; - - if let Some(left) = left { - // It's only possible to suppress the formatting of the whole binary expression formatting OR - // the formatting of the right hand side value but not of a nested binary expression. - f.context() - .comments() - .mark_suppression_checked(left.syntax()); - flatten_items.flatten_binary_expression_right_hand_side(left, Some(parent_operator))?; - } else { - // Leaf binary like expression. Format the left hand side. - // The right hand side gets formatted when traversing upwards in the tree. - let left = parent.left()?; - let has_comments = left.syntax().has_comments_direct(); - - flatten_items.items.push(FlattenItem::new( - FlattenedBinaryExpressionPart::Left { expression: left }, - Some(parent_operator), - has_comments.into(), - )); - } +declare_node_union! { + pub(crate) JsAnyBinaryLikeExpression = JsLogicalExpression | JsBinaryExpression | JsInstanceofExpression | JsInExpression +} - left = Some(parent); - } +impl Format for JsAnyBinaryLikeExpression { + fn fmt(&self, f: &mut Formatter) -> FormatResult<()> { + let parent = self.resolve_parent(); - // Format the top most binary like expression - if let Some(root) = left { - flatten_items.flatten_binary_expression_right_hand_side(root, None)?; - } + let is_inside_condition = self.is_inside_condition(parent.as_ref()); + let parts = split_into_left_and_right_sides(self, is_inside_condition)?; - let group = FlattenedBinaryExpressionPart::Group { - current: JsAnyBinaryLikeLeftExpression::JsAnyExpression(current_node.into_expression()), - expressions_start: flatten_items.current_group_start, - expressions_end: flatten_items.len(), - parenthesized: false, - }; + // Don't indent inside of conditions because conditions add their own indent and grouping. + if is_inside_condition { + return write!(f, [&format_once(|f| { f.join().entries(parts).finish() })]); + } - group.write(f, &flatten_items) -} + if let Some(parent) = parent.as_ref() { + // Add a group with a soft block indent in cases where it is necessary to parenthesize the binary expression. + // For example, `(a+b)(call)`, `!(a + b)`, `(a + b).test`. + if is_callee(self.syntax(), parent) + || JsUnaryExpression::can_cast(parent.kind()) + || JsAnyStaticMemberLike::can_cast(parent.kind()) + { + return write!( + f, + [group(&soft_block_indent(&format_once(|f| { + f.join().entries(parts).finish() + })))] + ); + } + } -/// Small wrapper to identify the operation of an expression and deduce their precedence -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub(crate) enum BinaryLikeOperator { - Logical(JsLogicalOperator), - Binary(JsBinaryOperator), - Instanceof, - In, -} + let should_not_indent = self.should_not_indent_if_parent_indents(parent.as_ref()); + let inline_logical_expression = self.should_inline_logical_expression(); + let should_indent_if_inlines = should_indent_if_parent_inlines(parent.as_ref()); + + let flattened = parts.len() > 2; + + if should_not_indent + || (inline_logical_expression && !flattened) + || (!inline_logical_expression && should_indent_if_inlines) + { + return write!( + f, + [group(&format_once(|f| { + f.join().entries(parts).finish() + }))] + ); + } -impl BinaryLikeOperator { - pub const fn precedence(&self) -> OperatorPrecedence { - match self { - BinaryLikeOperator::Logical(logical) => logical.precedence(), - BinaryLikeOperator::Binary(binary) => binary.precedence(), - BinaryLikeOperator::Instanceof | BinaryLikeOperator::In => { - OperatorPrecedence::Relational + if let Some(first) = parts.first() { + let last_is_jsx = parts.last().map_or(false, |part| part.is_jsx()); + let tail_parts = if last_is_jsx { + &parts[1..parts.len() - 1] + } else { + &parts[1..] + }; + + let group_id = f.group_id("logicalChain"); + + let format_non_jsx_parts = format_with(|f| { + write!( + f, + [group(&format_args![ + first, + indent(&format_once(|f| { + f.join().entries(tail_parts.iter()).finish() + })) + ]) + .with_group_id(Some(group_id))] + ) + }); + + if last_is_jsx { + // SAFETY: `last_is_jsx` is only true if parts is not empty + let jsx_element = parts.last().unwrap().memoized(); + write!( + f, + [group(&format_args![ + format_non_jsx_parts, + if_group_breaks(&block_indent(&jsx_element)).with_group_id(Some(group_id)), + if_group_fits_on_line(&jsx_element).with_group_id(Some(group_id)) + ])] + ) + } else { + write!(f, [format_non_jsx_parts]) } + } else { + // Empty, should never ever happen but let's gracefully recover. + Ok(()) } } - - pub const fn is_remainder(&self) -> bool { - matches!( - self, - BinaryLikeOperator::Binary(JsBinaryOperator::Remainder) - ) - } } -impl From for BinaryLikeOperator { - fn from(operator: JsLogicalOperator) -> Self { - BinaryLikeOperator::Logical(operator) +/// Creates a [BinaryLeftOrRightSide::Left] for the first left hand side that: +/// * isn't a [JsBinaryLikeExpression] +/// * is a [JsBinaryLikeExpression] but it should be formatted as its own group (see [JsAnyBinaryLikeExpression::can_flatten]). +/// +/// It then traverses upwards from the left most node and creates [BinaryLikeLeftOrRightSide::Right]s for +/// every [JsBinaryLikeExpression] until it reaches the root again. +fn split_into_left_and_right_sides( + root: &JsAnyBinaryLikeExpression, + inside_condition: bool, +) -> SyntaxResult> { + // Stores the left and right parts of the binary expression in sequence (rather than nested as they + // appear in the tree). + let mut items = Vec::new(); + + let mut expressions = BinaryLikePreorder::new(root.clone()); + + while let Some(event) = expressions.next() { + match event { + VisitEvent::Enter(binary) => { + if !binary.can_flatten()? { + // Stop at this expression. This is either not a binary expression OR it has + // different precedence and needs to be grouped separately. + // Calling skip_subtree prevents the exit event being triggered for this event. + expressions.skip_subtree(); + + items.push(BinaryLeftOrRightSide::Left { + is_root: binary.syntax() == root.syntax(), + parent: binary, + }); + } + } + VisitEvent::Exit(expression) => items.push(BinaryLeftOrRightSide::Right { + is_root: expression.syntax() == root.syntax(), + parent: expression, + inside_condition, + }), + } } -} -impl From for BinaryLikeOperator { - fn from(binary: JsBinaryOperator) -> Self { - BinaryLikeOperator::Binary(binary) - } + Ok(items) } -// False positive, Removing the `+ 'a` lifetime fails to compile with `hidden type for `impl Trait` captures lifetime that does not appear in bounds` -#[allow(clippy::needless_lifetimes)] -fn format_sub_expression<'a>( - sub_expression: &'a JsAnyBinaryLikeLeftExpression, -) -> impl Format + 'a { - format_with(move |f| { - if binary_argument_needs_parens(sub_expression) { - format_parenthesize( - sub_expression.syntax().first_token().as_ref(), - &sub_expression, - sub_expression.syntax().last_token().as_ref(), - ) - .grouped_with_soft_block_indent() - .fmt(f) - } else { - write!(f, [sub_expression]) - } - }) -} +fn should_flatten(parent_operator: BinaryLikeOperator, operator: BinaryLikeOperator) -> bool { + if operator.precedence() != parent_operator.precedence() { + return false; + } -fn keep_on_same_line(flatten_nodes: &[FlattenItem]) -> bool { - // We don't want to have 1 + 2 to break, for example. - // But if there are any trailing comments, break it. - flatten_nodes.len() <= 2 && flatten_nodes.iter().all(|node| !node.has_comments()) -} + match (parent_operator.precedence(), operator.precedence()) { + // `**` is right associative + (OperatorPrecedence::Exponential, _) => false, -fn is_inside_parenthesis(current_node: &JsSyntaxNode) -> bool { - let parent_kind = current_node.parent().map(|parent| parent.kind()); - - matches!( - parent_kind, - Some( - JsSyntaxKind::JS_IF_STATEMENT - | JsSyntaxKind::JS_DO_WHILE_STATEMENT - | JsSyntaxKind::JS_WHILE_STATEMENT - | JsSyntaxKind::JS_SWITCH_STATEMENT - | JsSyntaxKind::JS_TEMPLATE_ELEMENT - | JsSyntaxKind::TS_TEMPLATE_ELEMENT - ) - ) -} + // `a == b == c` => `(a == b) == c` + (OperatorPrecedence::Equality, OperatorPrecedence::Equality) => false, -/// This function checks whether the chain of logical/binary expressions **should not** be indented -/// -/// There are some cases where the indentation is done by the parent, so if the parent is already doing -/// the indentation, then there's no need to do a second indentation. -/// [Prettier applies]: https://github.com/prettier/prettier/blob/b0201e01ef99db799eb3716f15b7dfedb0a2e62b/src/language-js/print/binaryish.js#L122-L125 -fn should_not_indent_if_parent_indents(current_node: &JsAnyBinaryLikeLeftExpression) -> bool { - let parent = current_node - .syntax() - .ancestors() - .skip(1) - .find(|parent| parent.kind() != JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION); - - let parent_kind = parent.as_ref().map(|node| node.kind()); - - let great_parent = parent.and_then(|parent| parent.parent()); - let great_parent_kind = great_parent.map(|node| node.kind()); - - match (parent_kind, great_parent_kind) { - (Some(JsSyntaxKind::JS_PROPERTY_OBJECT_MEMBER), _) - | (Some(JsSyntaxKind::JS_INITIALIZER_CLAUSE), Some(JsSyntaxKind::JS_VARIABLE_DECLARATOR)) => { - current_node - .as_expression() - .and_then(|expression| should_break_after_operator(expression).ok()) - .unwrap_or(false) + (OperatorPrecedence::Multiplicative, OperatorPrecedence::Multiplicative) => { + // `a * 3 % 5` -> `(a * 3) % 5` + if parent_operator == BinaryLikeOperator::Binary(JsBinaryOperator::Remainder) + || operator == BinaryLikeOperator::Binary(JsBinaryOperator::Remainder) + { + false + } + // `a * 3 / 5` -> `(a * 3) / 5 + else { + parent_operator == operator + } } - ( - Some( - JsSyntaxKind::JS_RETURN_STATEMENT - | JsSyntaxKind::JS_THROW_STATEMENT - | JsSyntaxKind::JS_ARROW_FUNCTION_EXPRESSION, - ), - _, - ) => true, - _ => false, + // `a << 3 << 4` -> `(a << 3) << 4` + (OperatorPrecedence::Shift, OperatorPrecedence::Shift) => false, + _ => true, } } -/// There are other cases where the parent decides to inline the the element; in +/// There are cases where the parent decides to inline the the element; in /// these cases the decide to actually break on a new line and indent it. /// /// This function checks what the parents adheres to this behaviour -fn should_indent_if_parent_inlines(current_node: &JsAnyBinaryLikeLeftExpression) -> bool { - let parent = current_node.syntax().parent(); - let grand_parent = parent.as_ref().and_then(|p| p.parent()); - - match (parent, grand_parent) { - (Some(parent), Some(grand_parent)) => { - parent.kind() == JsSyntaxKind::JS_INITIALIZER_CLAUSE - && grand_parent.kind() == JsSyntaxKind::JS_VARIABLE_DECLARATOR +fn should_indent_if_parent_inlines(parent: Option<&JsSyntaxNode>) -> bool { + parent.map_or(false, |parent| match parent.kind() { + JsSyntaxKind::JS_ASSIGNMENT_EXPRESSION | JsSyntaxKind::JS_PROPERTY_OBJECT_MEMBER => true, + + JsSyntaxKind::JS_INITIALIZER_CLAUSE => { + resolve_parent(parent).map_or(false, |grand_parent| { + matches!( + grand_parent.kind(), + JsSyntaxKind::JS_VARIABLE_DECLARATOR | JsSyntaxKind::JS_PROPERTY_CLASS_MEMBER + ) + }) } - _ => false, - } -} - -#[derive(Debug, Default)] -struct FlattenItems { - items: Vec, - - /// Position into `items` where the next group starts. - current_group_start: usize, + }) } -impl Deref for FlattenItems { - type Target = [FlattenItem]; +/// Represents the right or left hand side of a binary expression. +#[derive(Debug, Clone)] +enum BinaryLeftOrRightSide { + /// A terminal left hand side of a binary expression. + /// + /// Formats the left hand side only. + Left { + parent: JsAnyBinaryLikeExpression, + is_root: bool, + }, - fn deref(&self) -> &Self::Target { - &self.items - } + /// The right hand side of a binary expression. + /// Formats the operand together with the right hand side. + Right { + parent: JsAnyBinaryLikeExpression, + /// Is the parent the condition of a `if` / `while` / `do-while` / `for` statement? + inside_condition: bool, + is_root: bool, + }, } -impl FlattenItems { - /// Formats the right hand side of a binary like expression - fn flatten_binary_expression_right_hand_side( - &mut self, - expression: JsAnyBinaryLikeExpression, - parent_operator: Option, - ) -> FormatResult<()> { - let should_flatten = expression.can_flatten()?; - - if should_flatten { - self.flatten_right_hand_side(expression, parent_operator) - } else { - self.flatten_new_binary_like_group(expression, parent_operator) - } - } - - /// Flattens the right hand operand of a binary like expression. - fn flatten_right_hand_side( - &mut self, - binary_like_expression: JsAnyBinaryLikeExpression, - parent_operator: Option, - ) -> FormatResult<()> { - let right = JsAnyBinaryLikeLeftExpression::JsAnyExpression(binary_like_expression.right()?); - let has_comments = right.syntax().has_comments_direct(); - - let flatten_item = FlattenItem::new( - FlattenedBinaryExpressionPart::Right { - parent: binary_like_expression, - }, - parent_operator, - has_comments.into(), - ); - self.items.push(flatten_item); - - Ok(()) - } - - /// The left hand-side expression and the current operator cannot be flattened. - /// Format the left hand side on its own and potentially wrap it in parentheses before formatting - /// the right-hand side of the current expression. - fn flatten_new_binary_like_group( - &mut self, - binary_like_expression: JsAnyBinaryLikeExpression, - parent_operator: Option, - ) -> FormatResult<()> { - if let Some(last) = self.items.last_mut() { - // Remove any line breaks and the trailing operator so that the operator/trailing aren't part - // of the parenthesized expression. - last.terminator = TrailingTerminator::None; - last.operator = None; - } - - let left = binary_like_expression.left()?; - let operator_token = binary_like_expression.operator_token()?; - - let operator_has_trailing_comments = operator_token.has_trailing_comments(); - let left_parenthesized = binary_argument_needs_parens(&left); - let mut left_item = FlattenItem::new( - FlattenedBinaryExpressionPart::Group { - current: left, - expressions_start: self.current_group_start, - expressions_end: self.items.len(), - parenthesized: left_parenthesized, - }, - Some(operator_token), - operator_has_trailing_comments.into(), - ); - - if operator_has_trailing_comments { - left_item = left_item.with_terminator(TrailingTerminator::HardLineBreak); - } - - self.current_group_start = self.len(); - self.items.push(left_item); - - let right = JsAnyBinaryLikeLeftExpression::JsAnyExpression(binary_like_expression.right()?); - - // Flatten the right node - let parent_operator_has_comments = parent_operator - .as_ref() - .map(|operator| operator.has_leading_comments()); - - let mut right_item = FlattenItem::new( - FlattenedBinaryExpressionPart::Right { - parent: binary_like_expression, +impl BinaryLeftOrRightSide { + #[allow(unused)] + fn is_jsx(&self) -> bool { + match self { + BinaryLeftOrRightSide::Left { parent, .. } => match parent.left() { + Ok(JsAnyBinaryLikeLeftExpression::JsAnyExpression(expression)) => { + matches!(expression.resolve(), JsAnyExpression::JsxTagExpression(_)) + } + _ => false, }, - parent_operator, - Commented::No, - ); - - // Format the parent operator - if let Some(parent_operator_has_comments) = parent_operator_has_comments { - // Here we care only about trailing comments that belong to the previous operator - if parent_operator_has_comments { - right_item = right_item - .with_comments(true) - .with_terminator(TrailingTerminator::HardLineBreak) + BinaryLeftOrRightSide::Right { parent, .. } => { + if let Ok(right) = parent.right().map(|right| right.into_resolved()) { + matches!(right, JsAnyExpression::JsxTagExpression(_)) + } else { + false + } } - } else { - // Here we want to check only leading comments; - // trailing comments will be added after the end of the whole expression. - // We want to handle cases like `lorem && (3 + 5 == 9) // comment`. - // This part is a signal to the formatter to tell it if the whole expression should break. - right_item = right_item.with_comments(right.syntax().has_leading_comments()) - }; - - self.items.push(right_item); - - Ok(()) - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -enum Commented { - Yes, - No, -} - -impl From for bool { - fn from(comments: Commented) -> Self { - match comments { - Commented::Yes => true, - Commented::No => false, } } } -impl From for Commented { - fn from(b: bool) -> Self { - match b { - true => Commented::Yes, - false => Commented::No, - } - } -} - -/// The left or right sub part of a binary expression. -#[derive(Debug)] -enum FlattenedBinaryExpressionPart { - /// The right hand side of a binary expression. Needs to format the parent operator and the right expression - Right { - /// The parent expression - parent: JsAnyBinaryLikeExpression, - }, - - /// The very first left hand side of a binary expression. Only formats the expression - Left { - /// The left hand side expression - expression: JsAnyBinaryLikeLeftExpression, - }, - - /// A group of expressions that can be grouped/printed together. - Group { - /// The binary expression that should be formatted now - current: JsAnyBinaryLikeLeftExpression, - - /// Start end/index into the flattened items array from where the left hand side expressions start - expressions_start: usize, - expressions_end: usize, - - /// Whether to parenthesize the expression - parenthesized: bool, - }, -} -impl FlattenedBinaryExpressionPart { - fn write(&self, f: &mut JsFormatter, items: &[FlattenItem]) -> FormatResult<()> { +impl Format for BinaryLeftOrRightSide { + fn fmt(&self, f: &mut Formatter) -> FormatResult<()> { match self { - FlattenedBinaryExpressionPart::Right { parent } => { - let right = JsAnyBinaryLikeLeftExpression::JsAnyExpression(parent.right()?); - - write!(f, [format_sub_expression(&right)]) - } - FlattenedBinaryExpressionPart::Left { expression } => { - write!(f, [expression]) - } - FlattenedBinaryExpressionPart::Group { - current, - expressions_start, - expressions_end, - parenthesized, - } => { - let expressions = &items[*expressions_start..*expressions_end]; - let content = format_with(|f| { - let keep_on_same_line = keep_on_same_line(expressions); + BinaryLeftOrRightSide::Left { parent, is_root } => { + if !is_root { + for ancestor in parent.syntax().ancestors().skip(1) { + match ancestor.kind() { + JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION => { + f.context().comments().mark_suppression_checked(&ancestor); - let mut groups = expressions.iter().map(|group| { - format_with(|f| { - group.expression.write(f, items)?; + let parenthesized = + JsParenthesizedExpression::unwrap_cast(ancestor); - if let Some(operator) = &group.operator { - write!(f, [space(), operator.format()])?; + write!(f, [format_removed(&parenthesized.l_paren_token()?)])?; } - - match &group.terminator { - TrailingTerminator::None => (), - TrailingTerminator::HardLineBreak => { - write!(f, [hard_line_break()])? - } - }; - - Ok(()) - }) - }); - - if keep_on_same_line { - // we bail early if group doesn't need to be broken. We don't need to do further checks - f.join_with(space()).entries(groups).finish() - } else if is_inside_parenthesis(current.syntax()) { - f.join_with(soft_line_break_or_space()) - .entries(groups) - .finish() - } else if should_not_indent_if_parent_indents(current) { - write!( - f, - [group(&format_once(|f| { - f.join_with(soft_line_break_or_space()) - .entries(groups) - .finish() - }))] - ) - } else if should_indent_if_parent_inlines(current) { - write!( - f, - [soft_line_indent_or_space(&group(&format_once(|f| { - f.join_with(soft_line_break_or_space()) - .entries(groups) - .finish() - })))] - ) - } else { - // if none of the previous conditions is met, - // we take out the first element from the rest of the group - // and indent the rest of the groups in a new line - - // SAFETY: Safe because `keep_on_same_line` returns `true` if this is a single - // binary expression without any nested sub expressions. - write!(f, [groups.next().unwrap()])?; - - write!( - f, - [group(&soft_line_indent_or_space(&format_once(|f| { - f.join_with(soft_line_break_or_space()) - .entries(groups) - .finish() - })))] - ) + _ => break, + } } - }); - - if *parenthesized { - let first_token = current.syntax().first_token(); - let last_token = current.syntax().last_token(); - - format_parenthesize(first_token.as_ref(), &content, last_token.as_ref()) - .grouped_with_soft_block_indent() - .fmt(f) - } else { - write!(f, [content]) } + + write!(f, [group(&parent.left())]) } - } - } -} + BinaryLeftOrRightSide::Right { + parent: binary_like_expression, + inside_condition: inside_parenthesis, + is_root, + } => { + // It's only possible to suppress the formatting of the whole binary expression formatting OR + // the formatting of the right hand side value but not of a nested binary expression. + // This aligns with Prettier's behaviour. + f.context() + .comments() + .mark_suppression_checked(binary_like_expression.syntax()); -#[derive(Debug)] -struct FlattenItem { - expression: FlattenedBinaryExpressionPart, - operator: Option, - terminator: TrailingTerminator, - comments: Commented, -} + let right = binary_like_expression.right()?; + let operator_token = binary_like_expression.operator_token()?; -#[derive(Debug)] -enum TrailingTerminator { - None, - HardLineBreak, -} + let operator_and_right_expression = format_with(|f| { + let should_inline = binary_like_expression.should_inline_logical_expression(); -impl FlattenItem { - fn new( - expression: FlattenedBinaryExpressionPart, - operator: Option, - comments: Commented, - ) -> Self { - Self { - expression, - operator, - terminator: TrailingTerminator::None, - comments, - } - } + write!(f, [space(), operator_token.format()])?; - fn has_comments(&self) -> bool { - matches!(self.comments, Commented::Yes) - } + if should_inline { + write!(f, [space()])?; + } else { + write!(f, [soft_line_break_or_space()])?; + } - fn with_terminator(mut self, terminator: TrailingTerminator) -> Self { - self.terminator = terminator; - self - } + write!(f, [right.format()])?; - fn with_comments>(mut self, comments: I) -> Self { - self.comments = comments.into(); - self - } -} + if !is_root { + for ancestor in binary_like_expression.syntax().ancestors().skip(1) { + match ancestor.kind() { + JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION => { + let parenthesized = + JsParenthesizedExpression::unwrap_cast(ancestor); -/// The [PostorderIterator] visits every node twice. First on the way down to find the left most binary -/// like expression, then on the way back up when it yields the binary like expressions. -/// This enum encodes the information whatever the iterator is on its way down (`Enter`) or traversing -/// upwards (`Exit`). -#[derive(Debug)] -enum VisitEvent { - Enter(JsAnyBinaryLikeExpression), - Exit(JsAnyBinaryLikeExpression), -} + write!(f, [format_removed(&parenthesized.r_paren_token()?)])?; + } + _ => break, + } + } + } -/// Iterator that first returns the left-most binary-like expression and then traverses upwards to the start node. -/// The binary like expression nodes are yielded when traversing upwards. -/// -/// # Examples -/// -/// ```js -/// a && b && c && d -/// ``` -/// This produces a tree with the following shape: -/// -/// ```txt -/// && -/// / \ -/// / \ -/// && d -/// / \ -/// / \ -/// && c -/// / \ -/// a b -/// ``` -/// -/// The iterator follows the left branches of the binary expressions without until it hits any non -/// binary-like expression (in this case the reference identifier `a`). From there, the iterator starts -/// traversing upwards again and yields the binary expression along the way. The returned nodes for the above -/// examples are (in that exact order): -/// 1. `a && b` -/// 2. `a && b && c` -/// 3. `a && b && c && d` -struct PostorderIterator { - /// The next node to visit or [None] if the iterator passed the start node (is at its end). - next: Option, + Ok(()) + }); - /// The start node. Necessary to know when to stop iterating. - start: JsSyntaxNode, -} + let syntax = binary_like_expression.syntax(); + let parent = resolve_parent(syntax); -impl PostorderIterator { - fn new(start: JsAnyBinaryLikeExpression) -> Self { - Self { - start: start.syntax().clone(), - next: Some(VisitEvent::Enter(start)), - } - } -} + // Doesn't match prettier that only distinguishes between logical and binary + let parent_has_same_kind = parent.as_ref().map_or(false, |parent| { + is_same_binary_expression_kind(binary_like_expression, &parent) + }); -impl Iterator for PostorderIterator { - type Item = JsAnyBinaryLikeExpression; + let left_has_same_kind = + binary_like_expression + .left()? + .into_expression() + .map_or(false, |left| { + is_same_binary_expression_kind( + binary_like_expression, + &left.resolve_syntax(), + ) + }); + let right_has_same_kind = + is_same_binary_expression_kind(binary_like_expression, &right.resolve_syntax()); - fn next(&mut self) -> Option { - loop { - match self.next.take()? { - VisitEvent::Enter(binary) => { - let left_expression = binary - .left() - .ok() - .and_then(|left| left.as_expression().cloned()) - .and_then(|left| JsAnyBinaryLikeExpression::cast(left.syntax().clone())); - - if let Some(expression) = left_expression { - self.next = Some(VisitEvent::Enter(expression)); + let should_break = { + if has_token_trailing_line_comment(&operator_token) { + true } else { - // If left is missing or it isn't a binary like expression, then format it as part of the parent binary like expression - self.next = Some(VisitEvent::Exit(binary)); + let mut current = Some(binary_like_expression.left()?.into_syntax()); + loop { + if let Some(left) = current { + if has_leading_own_line_comment(&left) { + break true; + } + + match left.kind() { + JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION => { + let parenthesized = + JsParenthesizedExpression::unwrap_cast(left); + + current = parenthesized + .expression() + .ok() + .map(AstNode::into_syntax); + } + _ => { + break false; + } + } + } + } } + }; + + let should_group = { + !(*inside_parenthesis + && matches!( + binary_like_expression, + JsAnyBinaryLikeExpression::JsLogicalExpression(_) + )) + && !parent_has_same_kind + && !left_has_same_kind + && !right_has_same_kind + }; + + if !should_break && should_group { + write!(f, [group(&operator_and_right_expression)])?; + } else { + write!(f, [operator_and_right_expression])?; } - VisitEvent::Exit(node) => { - if node.syntax() != &self.start { - self.next = node.syntax().parent().map(|parent| { - // SAFETY: Calling `unwrap` here is safe because the iterator only enters (traverses into) a node - // if it is a valid binary like expression. - let expression = JsAnyBinaryLikeExpression::cast(parent).unwrap(); - VisitEvent::Exit(expression) - }); - } - return Some(node); + // This is not ideal but it fixes an instability issue when the right hand side has a trailing line comment + // `a && b // comment` -> `a &&\n b; // comment` (see how the comment moved after the `;`) + if has_trailing_line_comment(right.syntax()) + && parent.map_or(false, |parent| { + parent.kind() == JsSyntaxKind::JS_EXPRESSION_STATEMENT + }) + { + write!(f, [line_suffix_boundary()])?; } + + Ok(()) } } } } -impl FusedIterator for PostorderIterator {} - -declare_node_union! { - pub(crate) JsAnyBinaryLikeExpression = JsLogicalExpression | JsBinaryExpression | JsInstanceofExpression | JsInExpression -} - impl JsAnyBinaryLikeExpression { - pub fn left(&self) -> SyntaxResult { + pub(crate) fn left(&self) -> SyntaxResult { match self { JsAnyBinaryLikeExpression::JsLogicalExpression(logical) => logical .left() @@ -753,7 +499,8 @@ impl JsAnyBinaryLikeExpression { } } - pub fn right(&self) -> SyntaxResult { + /// Returns the right hand side of the binary like expression. + pub(crate) fn right(&self) -> SyntaxResult { match self { JsAnyBinaryLikeExpression::JsLogicalExpression(logical) => logical.right(), JsAnyBinaryLikeExpression::JsBinaryExpression(binary) => binary.right(), @@ -762,80 +509,147 @@ impl JsAnyBinaryLikeExpression { } } - fn into_expression(self) -> JsAnyExpression { - match self { - JsAnyBinaryLikeExpression::JsLogicalExpression(logical) => { - JsAnyExpression::JsLogicalExpression(logical) - } - JsAnyBinaryLikeExpression::JsBinaryExpression(binary) => { - JsAnyExpression::JsBinaryExpression(binary) - } - JsAnyBinaryLikeExpression::JsInstanceofExpression(instanceof) => { - JsAnyExpression::JsInstanceofExpression(instanceof) - } - JsAnyBinaryLikeExpression::JsInExpression(in_expression) => { - JsAnyExpression::JsInExpression(in_expression) - } + /// Returns `true` if the expression is inside of a test condition of `parent`. + /// + /// # Examples + /// + /// ```javascript + /// if (a + b) {} // true + /// if (true) { a + b } // false + /// switch (a + b) {} // true + /// ``` + fn is_inside_condition(&self, parent: Option<&JsSyntaxNode>) -> bool { + parent.map_or(false, |parent| { + let test = match parent.kind() { + JsSyntaxKind::JS_IF_STATEMENT => JsIfStatement::unwrap_cast(parent.clone()).test(), + JsSyntaxKind::JS_DO_WHILE_STATEMENT => { + JsDoWhileStatement::unwrap_cast(parent.clone()).test() + } + JsSyntaxKind::JS_WHILE_STATEMENT => { + JsWhileStatement::unwrap_cast(parent.clone()).test() + } + JsSyntaxKind::JS_SWITCH_STATEMENT => { + JsSwitchStatement::unwrap_cast(parent.clone()).discriminant() + } + _ => return false, + }; + + test.map_or(false, |test| &test.resolve_syntax() == self.syntax()) + }) + } + + /// Determines if a binary like expression should be flattened or not. As a rule of thumb, an expression + /// can be flattened if its left hand side has the same operator-precedence + fn can_flatten(&self) -> SyntaxResult { + let left = self.left()?.into_expression(); + + let left_expression = left.as_ref().map(|expression| expression.resolve_syntax()); + + if let Some(left_binary_like) = left_expression.and_then(JsAnyBinaryLikeExpression::cast) { + let operator = self.operator()?; + let left_operator = left_binary_like.operator()?; + + Ok(should_flatten(operator, left_operator)) + } else { + Ok(false) } } - /// Determines if a binary like expression should be inline or not. - pub fn should_inline(&self) -> bool { + pub(crate) fn should_inline_logical_expression(&self) -> bool { match self { - JsAnyBinaryLikeExpression::JsLogicalExpression(logical_expression) => { - match logical_expression.right() { - Ok(JsAnyExpression::JsObjectExpression(object_expression)) => { - object_expression.members().iter().count() > 0 - } - Ok(JsAnyExpression::JsArrayExpression(array_expression)) => { - array_expression.elements().iter().count() > 0 - } - _ => false, - } + JsAnyBinaryLikeExpression::JsLogicalExpression(logical) => { + logical + .right() + .map_or(false, |right| match right.resolve() { + JsAnyExpression::JsObjectExpression(object) => !object.members().is_empty(), + JsAnyExpression::JsArrayExpression(array) => !array.elements().is_empty(), + JsAnyExpression::JsxTagExpression(_) => true, + _ => false, + }) } _ => false, } } - /// Determines if the left expression can be flattened together with this expression. - /// - /// Returns `false` if the left hand side isn't a binary like expression and otherwise. - /// - /// Delegates to [should_flatten] for all other expressions. - fn can_flatten(&self) -> SyntaxResult { - let left = self.left()?; - - let result = if let Some(left) = JsAnyBinaryLikeExpression::cast(left.into_syntax()) { - should_flatten(self.operator()?, left.operator()?) - } else { - false - }; - Ok(result) + /// This function checks whether the chain of logical/binary expressions **should not** be indented + /// + /// There are some cases where the indentation is done by the parent, so if the parent is already doing + /// the indentation, then there's no need to do a second indentation. + /// [Prettier applies]: https://github.com/prettier/prettier/blob/b0201e01ef99db799eb3716f15b7dfedb0a2e62b/src/language-js/print/binaryish.js#L122-L125 + fn should_not_indent_if_parent_indents( + self: &JsAnyBinaryLikeExpression, + parent: Option<&JsSyntaxNode>, + ) -> bool { + parent.map_or(false, |parent| match parent.kind() { + JsSyntaxKind::JS_RETURN_STATEMENT | JsSyntaxKind::JS_THROW_STATEMENT => true, + JsSyntaxKind::JSX_EXPRESSION_ATTRIBUTE_VALUE => true, + JsSyntaxKind::JS_TEMPLATE_ELEMENT => true, + JsSyntaxKind::JS_FOR_STATEMENT => true, + JsSyntaxKind::JS_ARROW_FUNCTION_EXPRESSION => { + let arrow = JsArrowFunctionExpression::unwrap_cast(parent.clone()); + + arrow + .body() + .ok() + .and_then(|body| match body { + JsAnyFunctionBody::JsAnyExpression(expression) => { + Some(expression.into_resolved_syntax()) + } + JsAnyFunctionBody::JsFunctionBody(_) => None, + }) + .as_ref() + == Some(self.syntax()) + } + JsSyntaxKind::JS_CONDITIONAL_EXPRESSION => { + let grand_parent = resolve_parent(&parent); + + grand_parent.map_or(false, |grand_parent| { + !matches!( + grand_parent.kind(), + JsSyntaxKind::JS_RETURN_STATEMENT + | JsSyntaxKind::JS_THROW_STATEMENT + | JsSyntaxKind::JS_CALL_EXPRESSION + | JsSyntaxKind::JS_IMPORT_CALL_EXPRESSION + | JsSyntaxKind::META + ) + }) + } + _ => false, + }) } } impl From for JsAnyExpression { - fn from(binary_like: JsAnyBinaryLikeExpression) -> Self { - match binary_like { - JsAnyBinaryLikeExpression::JsLogicalExpression(logical) => logical.into(), - JsAnyBinaryLikeExpression::JsBinaryExpression(binary) => binary.into(), - JsAnyBinaryLikeExpression::JsInstanceofExpression(instanceof) => instanceof.into(), - JsAnyBinaryLikeExpression::JsInExpression(in_expression) => in_expression.into(), + fn from(binary: JsAnyBinaryLikeExpression) -> Self { + match binary { + JsAnyBinaryLikeExpression::JsLogicalExpression(expression) => expression.into(), + JsAnyBinaryLikeExpression::JsBinaryExpression(expression) => expression.into(), + JsAnyBinaryLikeExpression::JsInstanceofExpression(expression) => expression.into(), + JsAnyBinaryLikeExpression::JsInExpression(expression) => expression.into(), } } } -/// This function returns `true` when the binary expression should be wrapped in parentheses to either -/// * a) correctly encode precedence -/// * b) Improve readability by adding parentheses around expressions where the precedence may not be obvious to many readers. -pub(crate) fn binary_argument_needs_parens(node: &JsAnyBinaryLikeLeftExpression) -> bool { - if let Some(binary_like) = JsAnyBinaryLikeExpression::cast(node.syntax().clone()) { - binary_like.needs_parentheses() - } else { - false +impl NeedsParentheses for JsAnyBinaryLikeExpression { + fn needs_parentheses_with_parent(&self, parent: &JsSyntaxNode) -> bool { + match self { + JsAnyBinaryLikeExpression::JsLogicalExpression(expression) => { + expression.needs_parentheses_with_parent(parent) + } + JsAnyBinaryLikeExpression::JsBinaryExpression(expression) => { + expression.needs_parentheses_with_parent(parent) + } + JsAnyBinaryLikeExpression::JsInstanceofExpression(expression) => { + expression.needs_parentheses_with_parent(parent) + } + JsAnyBinaryLikeExpression::JsInExpression(expression) => { + expression.needs_parentheses_with_parent(parent) + } + } } } +/// Implements the rules when a node needs parentheses that are common across all [JsAnyBinaryLikeExpression] nodes. pub(crate) fn needs_binary_like_parentheses( node: &JsAnyBinaryLikeExpression, parent: &JsSyntaxNode, @@ -909,89 +723,13 @@ pub(crate) fn needs_binary_like_parentheses( } } -impl NeedsParentheses for JsAnyBinaryLikeExpression { - fn needs_parentheses(&self) -> bool { - match self { - JsAnyBinaryLikeExpression::JsLogicalExpression(logical) => logical.needs_parentheses(), - JsAnyBinaryLikeExpression::JsBinaryExpression(binary) => binary.needs_parentheses(), - JsAnyBinaryLikeExpression::JsInstanceofExpression(instanceof) => { - instanceof.needs_parentheses() - } - JsAnyBinaryLikeExpression::JsInExpression(in_expression) => { - in_expression.needs_parentheses() - } - } - } - - fn needs_parentheses_with_parent(&self, parent: &JsSyntaxNode) -> bool { - match self { - JsAnyBinaryLikeExpression::JsLogicalExpression(logical) => { - logical.needs_parentheses_with_parent(parent) - } - JsAnyBinaryLikeExpression::JsBinaryExpression(binary) => { - binary.needs_parentheses_with_parent(parent) - } - JsAnyBinaryLikeExpression::JsInstanceofExpression(instanceof) => { - instanceof.needs_parentheses_with_parent(parent) - } - JsAnyBinaryLikeExpression::JsInExpression(in_expression) => { - in_expression.needs_parentheses_with_parent(parent) - } - } - } -} - -/// Returns `true` if a binary expression nested into another binary expression should be flattened together. -/// -/// This is generally the case if both operator have the same precedence. See the inline comments for the exceptions -/// to that rule. -fn should_flatten(parent_operator: BinaryLikeOperator, child_operator: BinaryLikeOperator) -> bool { - let parent_precedence = parent_operator.precedence(); - let child_precedence = child_operator.precedence(); - - if parent_precedence != child_precedence { - return false; - } - - // `**` is right associative. - if parent_precedence.is_exponential() { - return false; - } - // avoid `a == b == c` -> `(a == b) == c` - - if parent_precedence.is_equality() && child_precedence.is_equality() { - return false; - } - - // `a % b * c` -> `(a % b) * c` - // `a * b % c` -> `(a * b) % c` - if (child_operator.is_remainder() && parent_precedence.is_multiplicative()) - || (parent_operator.is_remainder() && child_precedence.is_multiplicative()) - { - return false; - } - - // `a * b / c` -> `(a * b) / c` - if child_operator != parent_operator - && child_precedence.is_multiplicative() - && parent_precedence.is_multiplicative() - { - return false; - } - // `a >> b >> c` -> `(a >> b) >> c` - if parent_precedence.is_shift() && child_precedence.is_shift() { - return false; - } - - true -} - declare_node_union! { + /// Union type for any valid left hand side of a [JsAnyBinaryLikeExpression]. pub(crate) JsAnyBinaryLikeLeftExpression = JsAnyExpression | JsPrivateName } impl JsAnyBinaryLikeLeftExpression { - fn as_expression(&self) -> Option<&JsAnyExpression> { + fn into_expression(self) -> Option { match self { JsAnyBinaryLikeLeftExpression::JsAnyExpression(expression) => Some(expression), JsAnyBinaryLikeLeftExpression::JsPrivateName(_) => None, @@ -1044,3 +782,303 @@ impl From for JsAnyBinaryLikeLeftExpression { } } } + +/// Union over all binary like operators. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub(crate) enum BinaryLikeOperator { + Logical(JsLogicalOperator), + Binary(JsBinaryOperator), + Instanceof, + In, +} + +impl BinaryLikeOperator { + pub const fn precedence(&self) -> OperatorPrecedence { + match self { + BinaryLikeOperator::Logical(logical) => logical.precedence(), + BinaryLikeOperator::Binary(binary) => binary.precedence(), + BinaryLikeOperator::Instanceof | BinaryLikeOperator::In => { + OperatorPrecedence::Relational + } + } + } + + pub const fn is_remainder(&self) -> bool { + matches!( + self, + BinaryLikeOperator::Binary(JsBinaryOperator::Remainder) + ) + } +} + +impl From for BinaryLikeOperator { + fn from(operator: JsLogicalOperator) -> Self { + BinaryLikeOperator::Logical(operator) + } +} + +impl From for BinaryLikeOperator { + fn from(binary: JsBinaryOperator) -> Self { + BinaryLikeOperator::Binary(binary) + } +} + +fn is_same_binary_expression_kind( + binary: &JsAnyBinaryLikeExpression, + other: &JsSyntaxNode, +) -> bool { + match binary { + JsAnyBinaryLikeExpression::JsLogicalExpression(_) => { + matches!(other.kind(), JsSyntaxKind::JS_LOGICAL_EXPRESSION) + } + JsAnyBinaryLikeExpression::JsBinaryExpression(_) + | JsAnyBinaryLikeExpression::JsInstanceofExpression(_) + | JsAnyBinaryLikeExpression::JsInExpression(_) => { + matches!( + other.kind(), + JsSyntaxKind::JS_BINARY_EXPRESSION + | JsSyntaxKind::JS_INSTANCEOF_EXPRESSION + | JsSyntaxKind::JS_IN_EXPRESSION + ) + } + } +} + +/// The [BinaryLikePreorder] visits every node twice. First on the way down to find the left most binary +/// like expression, then on the way back up. This enum encodes the information whatever the +/// iterator is on its way down (`Enter`) or traversing upwards (`Exit`). +#[derive(Debug, Eq, PartialEq, Clone)] +enum VisitEvent { + Enter(JsAnyBinaryLikeExpression), + Exit(JsAnyBinaryLikeExpression), +} + +/// Iterator that visits [JsAnyBinaryLikeExpression]s in pre-order. +/// This is similar to [JsSyntaxNode::descendants] but it only traverses into [JsAnyBinaryLikeExpression] and their left side +/// (the right side is never visited). +/// +/// # Examples +/// +/// ```js +/// a && b && c && d +/// ``` +/// This produces a tree with the following shape: +/// +/// ```txt +/// && +/// / \ +/// / \ +/// && d && e +/// / \ +/// / \ +/// && c +/// / \ +/// a b +/// ``` +/// +/// The iterator emits the following events: +/// +/// * Enter(`a && b && c && d && e`) +/// * Enter(`a && b && c`) +/// * Enter(`a && b`) +/// * Exit(`a && b`) +/// * Exit(`a && b && c`) +/// * Exit(`a && b && c && d && e`) +/// +/// Notice how the iterator doesn't yield events for the terminal identifiers `a`, `b`, `c`, `d`, and `e`, +/// nor for the right hand side expression `d && e`. This is because the visitor only traverses into +/// [JsAnyBinaryLikeExpression]s and of those, only along the left side. +struct BinaryLikePreorder { + /// The next node to visit or [None] if the iterator passed the start node (is at its end). + next: Option, + + /// The start node. Necessary to know when to stop iterating. + start: JsSyntaxNode, + + skip_subtree: bool, +} + +impl BinaryLikePreorder { + fn new(start: JsAnyBinaryLikeExpression) -> Self { + Self { + start: start.syntax().clone(), + next: Some(VisitEvent::Enter(start)), + skip_subtree: false, + } + } + + fn skip_subtree(&mut self) { + self.next = self.next.take().and_then(|next| match next { + VisitEvent::Enter(binary) => { + if binary.syntax() == &self.start { + None + } else { + // SAFETY: Calling `unwrap` here is safe because the iterator only enters (traverses into) a node + // if it is a valid binary like expression and it is guaranteed to have a parent. + let expression = binary + .resolve_parent() + .and_then(JsAnyBinaryLikeExpression::cast) + .unwrap(); + + Some(VisitEvent::Exit(expression)) + } + } + VisitEvent::Exit(node) => Some(VisitEvent::Exit(node)), + }); + self.skip_subtree = false; + } +} + +impl Iterator for BinaryLikePreorder { + type Item = VisitEvent; + + fn next(&mut self) -> Option { + if self.skip_subtree { + self.skip_subtree(); + } + + let next = self.next.take()?; + match &next { + VisitEvent::Enter(binary) => { + let next = binary + .left() + .ok() + .and_then(|left| left.into_expression()) + .and_then(|expression| { + JsAnyBinaryLikeExpression::cast(expression.into_resolved_syntax()) + }); + + if let Some(binary) = next { + self.next = Some(VisitEvent::Enter(binary)); + } else { + // If left is missing or it isn't a binary like expression, then format it as part of the parent binary like expression + self.next = Some(VisitEvent::Exit(binary.clone())); + } + } + VisitEvent::Exit(node) => { + if node.syntax() != &self.start { + self.next = node.resolve_parent().map(|parent| { + // SAFETY: Calling `unwrap` here is safe because the iterator only enters (traverses into) a node + // if it is a valid binary like expression. + let expression = JsAnyBinaryLikeExpression::cast(parent).unwrap(); + VisitEvent::Exit(expression) + }); + } + } + }; + + Some(next) + } +} + +impl FusedIterator for BinaryLikePreorder {} + +#[cfg(test)] +mod tests { + use crate::utils::binary_like_expression::{BinaryLikePreorder, VisitEvent}; + use crate::utils::JsAnyBinaryLikeExpression; + use rome_js_parser::parse_module; + use rome_js_syntax::JsLogicalExpression; + use rome_rowan::AstNode; + + #[test] + fn in_order_visits_every_binary_like_expression() { + let parse = parse_module("a && b && c || d", 0); + let root = parse + .syntax() + .descendants() + .find_map(JsLogicalExpression::cast) + .unwrap(); + let a_and_b_and_c = JsLogicalExpression::unwrap_cast(root.left().unwrap().into_syntax()); + let a_and_b = JsLogicalExpression::unwrap_cast(a_and_b_and_c.left().unwrap().into_syntax()); + + let mut iterator = BinaryLikePreorder::new(JsAnyBinaryLikeExpression::from(root.clone())); + + assert_eq!( + iterator.next(), + Some(VisitEvent::Enter(JsAnyBinaryLikeExpression::from( + root.clone() + ))) + ); + assert_eq!( + iterator.next(), + Some(VisitEvent::Enter(JsAnyBinaryLikeExpression::from( + a_and_b_and_c.clone() + ))) + ); + assert_eq!( + iterator.next(), + Some(VisitEvent::Enter(JsAnyBinaryLikeExpression::from( + a_and_b.clone() + ))) + ); + + assert_eq!( + iterator.next(), + Some(VisitEvent::Exit(JsAnyBinaryLikeExpression::from(a_and_b))) + ); + assert_eq!( + iterator.next(), + Some(VisitEvent::Exit(JsAnyBinaryLikeExpression::from( + a_and_b_and_c + ))) + ); + assert_eq!( + iterator.next(), + Some(VisitEvent::Exit(JsAnyBinaryLikeExpression::from(root))) + ); + } + + #[test] + fn in_order_skip_subtree() { + let parse = parse_module("a && b && c || d", 0); + let root = parse + .syntax() + .descendants() + .find_map(JsLogicalExpression::cast) + .unwrap(); + let a_and_b_and_c = JsLogicalExpression::unwrap_cast(root.left().unwrap().into_syntax()); + + let mut iterator = BinaryLikePreorder::new(JsAnyBinaryLikeExpression::from(root.clone())); + + assert_eq!( + iterator.next(), + Some(VisitEvent::Enter(JsAnyBinaryLikeExpression::from( + root.clone() + ))) + ); + assert_eq!( + iterator.next(), + Some(VisitEvent::Enter(JsAnyBinaryLikeExpression::from( + a_and_b_and_c.clone() + ),)) + ); + + // skip over a && b + iterator.skip_subtree(); + + assert_eq!( + iterator.next(), + Some(VisitEvent::Exit(JsAnyBinaryLikeExpression::from( + a_and_b_and_c + ))) + ); + assert_eq!( + iterator.next(), + Some(VisitEvent::Exit(JsAnyBinaryLikeExpression::from(root))) + ); + } +} + +fn has_trailing_line_comment(node: &JsSyntaxNode) -> bool { + node.last_token() + .map_or(false, |token| has_token_trailing_line_comment(&token)) +} + +fn has_token_trailing_line_comment(token: &JsSyntaxToken) -> bool { + token + .trailing_trivia() + .pieces() + .filter_map(|piece| piece.as_comments()) + .any(|comment| JsCommentStyle.get_comment_kind(&comment).is_line()) +} diff --git a/crates/rome_js_formatter/src/utils/member_chain/chain_member.rs b/crates/rome_js_formatter/src/utils/member_chain/chain_member.rs index 4b648c4acc3..2efa1c00cca 100644 --- a/crates/rome_js_formatter/src/utils/member_chain/chain_member.rs +++ b/crates/rome_js_formatter/src/utils/member_chain/chain_member.rs @@ -1,5 +1,4 @@ use crate::context::TabWidth; -use crate::js::expressions::parenthesized_expression::is_expression_handling_parens; use crate::prelude::*; use rome_formatter::write; use rome_js_syntax::{ @@ -102,20 +101,11 @@ impl Format for ChainEntry { fn fmt(&self, f: &mut Formatter) -> FormatResult<()> { let parentheses = self.top_most_parentheses(); - let handles_parens = JsAnyExpression::cast(self.member().syntax().clone()) - .map_or(false, |expression| { - is_expression_handling_parens(&expression) - }); - if let Some(parentheses) = parentheses { let mut current = parentheses.clone(); loop { - if handles_parens { - write!(f, [format_removed(¤t.l_paren_token()?)])?; - } else { - write!(f, [current.l_paren_token().format()])?; - } + write!(f, [format_removed(¤t.l_paren_token()?)])?; match current.expression()? { JsAnyExpression::JsParenthesizedExpression(inner) => { @@ -132,11 +122,7 @@ impl Format for ChainEntry { let mut current = parentheses.clone(); loop { - if handles_parens { - write!(f, [format_removed(¤t.r_paren_token()?)])?; - } else { - write!(f, [current.r_paren_token().format()])?; - } + write!(f, [format_removed(¤t.r_paren_token()?)])?; match current.expression()? { JsAnyExpression::JsParenthesizedExpression(inner) => { diff --git a/crates/rome_js_formatter/src/utils/mod.rs b/crates/rome_js_formatter/src/utils/mod.rs index fe39d468a72..b098a254238 100644 --- a/crates/rome_js_formatter/src/utils/mod.rs +++ b/crates/rome_js_formatter/src/utils/mod.rs @@ -2,7 +2,6 @@ pub(crate) mod array; mod assignment_like; mod binary_like_expression; mod conditional; -mod simple; pub mod string_utils; pub(crate) mod format_class; @@ -17,10 +16,9 @@ mod typescript; pub(crate) use crate::parentheses::resolve_left_most_expression; use crate::prelude::*; -pub(crate) use assignment_like::{should_break_after_operator, JsAnyAssignmentLike}; +pub(crate) use assignment_like::JsAnyAssignmentLike; pub(crate) use binary_like_expression::{ - binary_argument_needs_parens, format_binary_like_expression, needs_binary_like_parentheses, - JsAnyBinaryLikeExpression, JsAnyBinaryLikeLeftExpression, + needs_binary_like_parentheses, JsAnyBinaryLikeExpression, JsAnyBinaryLikeLeftExpression, }; pub(crate) use conditional::JsAnyConditional; pub(crate) use member_chain::get_member_chain; @@ -30,7 +28,6 @@ use rome_formatter::{format_args, write, Buffer, VecBuffer}; use rome_js_syntax::{JsAnyExpression, JsAnyStatement, JsInitializerClause, JsLanguage, Modifiers}; use rome_js_syntax::{JsSyntaxKind, JsSyntaxNode, JsSyntaxToken}; use rome_rowan::{AstNode, AstNodeList, Direction}; -pub(crate) use simple::*; pub(crate) use string_utils::*; pub(crate) use typescript::should_hug_type; @@ -208,71 +205,6 @@ where nodes_and_modifiers } -/// This enum is used to extract a precedence from certain nodes. By comparing the precedence -/// of two nodes, it's possible to change the way certain node should be formatted. -/// -/// A use case, for example, is when comparing a node with its parent. If the parent has a lower -/// precedence, then the node can change its formatting. -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)] -pub(crate) enum FormatPrecedence { - /// No precedence given to these nodes - None, - - /// Low priority - Low, - - /// High priority - High, -} - -impl FormatPrecedence { - /// Use this function when you want to extract the precedence of the current node - /// based on whether it can parenthesised or not. - /// - /// This function is useful when we want to compare a node against its parent. If the parent has - /// lower precedence, it means that we can remove the parenthesis from the current node. - /// - /// An example can be: - /// - /// ```js - /// let a = ("simple expression") + " or not"; - /// ``` - /// - /// In this case, we have a parenthesised expression and its parent is a binary expression. - /// The first one will have [FormatPrecedence::Low] as priority and the second has - /// [FormatPrecedence::None] as priority. In this case, the parenthesis can be omitted. - pub fn with_precedence_for_parenthesis(node: Option<&JsSyntaxNode>) -> Self { - node.map_or(FormatPrecedence::None, |node| match node.kind() { - JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION => FormatPrecedence::Low, - - JsSyntaxKind::TS_AS_EXPRESSION - | JsSyntaxKind::TS_NON_NULL_ASSERTION_EXPRESSION - | JsSyntaxKind::TS_TYPE_ASSERTION_EXPRESSION - | JsSyntaxKind::JS_UNARY_EXPRESSION - | JsSyntaxKind::JS_LOGICAL_EXPRESSION - | JsSyntaxKind::JS_BINARY_EXPRESSION - | JsSyntaxKind::JS_TEMPLATE - | JsSyntaxKind::JS_SPREAD - | JsSyntaxKind::JS_STATIC_MEMBER_EXPRESSION - | JsSyntaxKind::JS_STATIC_MEMBER_ASSIGNMENT - | JsSyntaxKind::JS_CALL_EXPRESSION - | JsSyntaxKind::JS_NEW_EXPRESSION - | JsSyntaxKind::JS_CONDITIONAL_EXPRESSION - | JsSyntaxKind::JS_EXTENDS_CLAUSE - | JsSyntaxKind::TS_IMPLEMENTS_CLAUSE - | JsSyntaxKind::JS_AWAIT_EXPRESSION - | JsSyntaxKind::JS_YIELD_ARGUMENT - | JsSyntaxKind::JS_ARROW_FUNCTION_EXPRESSION - | JsSyntaxKind::JS_EXPRESSION_STATEMENT - | JsSyntaxKind::JS_RETURN_STATEMENT - | JsSyntaxKind::JS_COMPUTED_MEMBER_EXPRESSION - | JsSyntaxKind::JS_COMPUTED_MEMBER_ASSIGNMENT => FormatPrecedence::High, - - _ => FormatPrecedence::None, - }) - } -} - /// Format a some code followed by an optional semicolon, and performs /// semicolon insertion if it was missing in the input source and the /// preceding element wasn't an unknown node diff --git a/crates/rome_js_formatter/src/utils/simple.rs b/crates/rome_js_formatter/src/utils/simple.rs deleted file mode 100644 index e9e46d4888c..00000000000 --- a/crates/rome_js_formatter/src/utils/simple.rs +++ /dev/null @@ -1,229 +0,0 @@ -//! This module exposes utility functions for detecting "simple" expressions -//! -//! Simple expressions are expressions that are going to create a single group -//! anyway, so they don't need to be wrapped in a second one: this includes -//! object, array or parenthesized expressions, as well as function -//! declarations that have a high probability of breaking only in their body -//! group. -//! This last bit is defined recursively in [is_simple_function_expression] as -//! functions that only have a few (less than 3) identifier parameters, no type -//! parameter or return type and a block body: technically such a function -//! expression can still break in both the parameters and body group but the -//! small number of parameters makes it unlikely. -//! -//! The use case for detecting these "simple" expressions is to avoid creating -//! redundant groups in nested delimited expressions when only one would -//! suffice, for instance in call expressions: -//! -//! ```js -//! // Formatter output without handling of simple expressions -//! new Promise( -//! (resolve, reject) => { -//! resolve(); -//! }, -//! ); -//! -//! func( -//! { -//! key: 'value', -//! }, -//! ); -//! -//! // Formatter output with handling of simple expressions -//! new Promise((resolve, reject) => { -//! resolve(); -//! }); -//! -//! func({ -//! key: 'value', -//! }); -//! ``` - -use rome_js_syntax::{ - JsAnyArrowFunctionParameters, JsAnyBinding, JsAnyBindingPattern, JsAnyExpression, - JsAnyFormalParameter, JsAnyFunction, JsAnyFunctionBody, JsAnyParameter, JsArrayExpression, - JsArrayExpressionFields, JsFormalParameter, JsFormalParameterFields, JsFunctionBodyFields, - JsIdentifierBindingFields, JsObjectExpression, JsObjectExpressionFields, JsParameters, - JsParametersFields, JsSyntaxToken, -}; -use rome_rowan::{AstNode, AstSeparatedList, SyntaxResult}; - -/// Returns true is the passed [JsAnyExpression] is a simple function, array or object expression -pub(crate) fn is_simple_expression(node: &JsAnyExpression) -> SyntaxResult { - match node { - JsAnyExpression::JsArrayExpression(array) => is_simple_array_expression(array), - JsAnyExpression::JsObjectExpression(object) => is_simple_object_expression(object), - node => { - if let Some(func) = JsAnyFunction::cast(node.syntax().clone()) { - is_simple_function_expression(func) - } else { - Ok(false) - } - } - } -} - -/// Returns true if the passed [JsAnyFunction] does not have any comment, type -/// parameters, return type annotation and simple parameters (see [is_simple_function_parameters]) -pub(crate) fn is_simple_function_expression(func: JsAnyFunction) -> SyntaxResult { - if let Some(token) = func.async_token() { - if token_has_comments(&token) { - return Ok(false); - } - } - - if let Some(token) = func.function_token()? { - if token_has_comments(&token) { - return Ok(false); - } - } - - if let Some(token) = func.star_token() { - if token_has_comments(&token) { - return Ok(false); - } - } - - if let Some(id) = func.id()? { - if id.syntax().has_comments_direct() { - return Ok(false); - } - } - - if func.type_parameters().is_some() { - return Ok(false); - } - - match func.parameters()? { - JsAnyArrowFunctionParameters::JsAnyBinding(JsAnyBinding::JsIdentifierBinding( - identifier, - )) => { - if token_has_comments(&identifier.name_token()?) { - return Ok(false); - } - } - JsAnyArrowFunctionParameters::JsParameters(parameters) => { - if !is_simple_function_parameters(parameters)? { - return Ok(false); - } - } - _ => { - return Ok(false); - } - } - - if func.return_type_annotation().is_some() { - return Ok(false); - } - - match func.body()? { - JsAnyFunctionBody::JsFunctionBody(body) => { - let JsFunctionBodyFields { - l_curly_token, - directives: _, - statements: _, - r_curly_token, - } = body.as_fields(); - - // Only account for the leading comments on the opening token and the trailing - // comments on the closing tokens (the inner tokens will be part of the body group) - if l_curly_token?.has_leading_comments() || r_curly_token?.has_trailing_comments() { - return Ok(false); - } - } - _ => return Ok(false), - } - - Ok(true) -} - -fn is_simple_array_expression(node: &JsArrayExpression) -> SyntaxResult { - let JsArrayExpressionFields { - l_brack_token, - elements: _, - r_brack_token, - } = node.as_fields(); - - if l_brack_token?.has_leading_comments() || r_brack_token?.has_trailing_comments() { - return Ok(false); - } - - Ok(true) -} - -fn is_simple_object_expression(node: &JsObjectExpression) -> SyntaxResult { - let JsObjectExpressionFields { - l_curly_token, - members: _, - r_curly_token, - } = node.as_fields(); - - if l_curly_token?.has_leading_comments() || r_curly_token?.has_trailing_comments() { - return Ok(false); - } - - Ok(true) -} - -/// Returns true if the passed [JsParameters] has 2 or less parameters that are -/// all simple parameters (see [is_simple_parameter]) with no comments trivia -fn is_simple_function_parameters(node: JsParameters) -> SyntaxResult { - let JsParametersFields { - l_paren_token, - items, - r_paren_token, - } = node.as_fields(); - - if token_has_comments(&l_paren_token?) || token_has_comments(&r_paren_token?) { - return Ok(false); - } - - if items.len() >= 3 { - return Ok(false); - } - - for item in &items { - match item? { - JsAnyParameter::JsAnyFormalParameter(JsAnyFormalParameter::JsFormalParameter(node)) => { - if !is_simple_parameter(node)? { - return Ok(false); - } - } - _ => return Ok(false), - } - } - - Ok(true) -} - -/// Returns true if the passed [JsFormalParameter] is a single identifier -/// with no question mark token, type annotation or initializer -fn is_simple_parameter(node: JsFormalParameter) -> SyntaxResult { - let JsFormalParameterFields { - binding, - question_mark_token, - type_annotation, - initializer, - } = node.as_fields(); - - match binding? { - JsAnyBindingPattern::JsAnyBinding(JsAnyBinding::JsIdentifierBinding(ident)) => { - let JsIdentifierBindingFields { name_token } = ident.as_fields(); - if token_has_comments(&name_token?) { - return Ok(false); - } - } - _ => return Ok(false), - } - - if question_mark_token.is_some() || type_annotation.is_some() || initializer.is_some() { - return Ok(false); - } - - Ok(true) -} - -/// Returns true if the passed [SyntaxToken] has any comments -pub(crate) fn token_has_comments(token: &JsSyntaxToken) -> bool { - token.has_leading_comments() || token.has_trailing_comments() -} diff --git a/crates/rome_js_formatter/tests/specs/js/module/arrow/params.js.snap b/crates/rome_js_formatter/tests/specs/js/module/arrow/params.js.snap index 53da40020d6..9dd0d42b729 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/arrow/params.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/arrow/params.js.snap @@ -589,10 +589,11 @@ foo(( ) => {}); foo(( - a = 1 + f({ - a, + a = 1 + + f({ + a, - b, - }), + b, + }), ) => {}); diff --git a/crates/rome_js_formatter/tests/specs/js/module/assignment/assignment.js.snap b/crates/rome_js_formatter/tests/specs/js/module/assignment/assignment.js.snap index abf99cca1c7..0987083348f 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/assignment/assignment.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/assignment/assignment.js.snap @@ -240,9 +240,11 @@ logical_expression_1 = logical_expression_2 = longLongLongLongLongLongLongLongLongLongLongLongLongTooLongVar || 1337; binary_expression_1 = - 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132; + 13321321312312321311332132131231232131232132132132232132132132 + + 1332132131231232131232132132132; binary_expression_2 = - 1332132131231232131232132132132 + 13321321312312321312321321321321332132131231232131232132132132; + 1332132131231232131232132132132 + + 13321321312312321312321321321321332132131231232131232132132132; instanceof_expression = "321321312312ddddddddddddddddddddddd312312312312" instanceof Object; in_expression = @@ -260,7 +262,8 @@ conditional_expression_2 = ? {} : {}; conditional_expression_3 = - 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 + 13321321312312321311332132131231232131232132132132232132132132 + + 1332132131231232131232132132132 ? {} : {}; conditional_expression_4 = @@ -274,7 +277,8 @@ b = ? {} : {}; c = - 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 + 13321321312312321311332132131231232131232132132132232132132132 + + 1332132131231232131232132132132 ? {} : {}; d = @@ -283,8 +287,8 @@ g = { long_key: "123123213123213123edwqdqwdasdasdsaewqewqewqdas" } in "long_key"; blablah = "aldkfkladfskladklsfkladklfkaldfadfkdaf" + - "adlfasdklfkldsklfakldsfkladsfkadsfladsfa" + - "dflkadfkladsfklkadlfkladlfkadklfjadlfdfdaf"; + "adlfasdklfkldsklfakldsfkladsfkadsfladsfa" + + "dflkadfkladsfklkadlfkladlfkadklfjadlfdfdaf"; fn = // something fn(); @@ -402,8 +406,4 @@ a = { 62: "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; 64: "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; 66: "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; - 74: 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132; - 76: 1332132131231232131232132132132 + 13321321312312321312321321321321332132131231232131232132132132; - 94: 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 - 108: 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 diff --git a/crates/rome_js_formatter/tests/specs/js/module/comments.js.snap b/crates/rome_js_formatter/tests/specs/js/module/comments.js.snap index 5e127012789..e86b472ab5d 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/comments.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/comments.js.snap @@ -154,14 +154,10 @@ function name( group, ) /* comment */ {} -4 + /* plus trailing */ -3 * 2 /* 2 trailing */; - -/* leading of opening */ ( - /* trailing of opening */ - 4 + 3 - /* leading of closing */ -) /* trailing of closing */; +4 + /* plus trailing */ 3 * 2 /* 2 trailing */; + +/* leading of opening */ /* trailing of opening */ 4 + 3 +/* leading of closing */ /* trailing of closing */; [3 /* trailing num */ /* trailing sep */]; diff --git a/crates/rome_js_formatter/tests/specs/js/module/export/expression_clause.js.snap b/crates/rome_js_formatter/tests/specs/js/module/export/expression_clause.js.snap index 02e10c52a3e..c38ee9362ed 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/export/expression_clause.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/export/expression_clause.js.snap @@ -13,5 +13,5 @@ Line width: 80 Quote style: Double Quotes Quote properties: As needed ----- -export default (1 - 43); +export default 1 - 43; diff --git a/crates/rome_js_formatter/tests/specs/js/module/expression/binaryish_expression.js.snap b/crates/rome_js_formatter/tests/specs/js/module/expression/binaryish_expression.js.snap index 69341d3e160..ff9753d1683 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/expression/binaryish_expression.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/expression/binaryish_expression.js.snap @@ -13,7 +13,6 @@ Line width: 80 Quote style: Double Quotes Quote properties: As needed ----- -2 > (4 + ((4 * 24) % 3)) << 23 instanceof Number in data || ( - a in status instanceof String + 15 && foo && bar && lorem instanceof String -); +2 > (4 + ((4 * 24) % 3)) << 23 instanceof Number in data || + (a in status instanceof String + 15 && foo && bar && lorem instanceof String); diff --git a/crates/rome_js_formatter/tests/specs/js/module/expression/conditional_expression.js.snap b/crates/rome_js_formatter/tests/specs/js/module/expression/conditional_expression.js.snap index de402f7ce2e..c80d5a7ae1d 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/expression/conditional_expression.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/expression/conditional_expression.js.snap @@ -23,7 +23,7 @@ Quote style: Double Quotes Quote properties: As needed ----- a ? b : c; -d ? (e + f) : (g + h); +d ? e + f : g + h; somethingThatsAReallyLongPropName ? somethingThatsAReallyLongPropName diff --git a/crates/rome_js_formatter/tests/specs/js/module/expression/logical_expression.js.snap b/crates/rome_js_formatter/tests/specs/js/module/expression/logical_expression.js.snap index 907ce8f29c8..0975e69a094 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/expression/logical_expression.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/expression/logical_expression.js.snap @@ -186,7 +186,7 @@ while ( somethingsomethingsomethingsomethin ) {} -(something && elsewhere && happy && thoughts); +something && elsewhere && happy && thoughts; function a() { return ( @@ -234,55 +234,51 @@ const a = x + y; } if ( - ( - somethingsomethingsomethingsomethin && somethingsomethingsomethingsomethin - ) || ( - somethingsomethingsomethingsomethin && somethingsomethingsomethingsomethin - ) + (somethingsomethingsomethingsomethin && + somethingsomethingsomethingsomethin) || + (somethingsomethingsomethingsomethin && somethingsomethingsomethingsomethin) ) { } -undefined === function () { - throw undefined; -}; +undefined === + function () { + throw undefined; + }; -const b = `${( - veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar -)}`; +const b = `${ + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar +}`; const a = - ( - aa && - bb && - something && - elsewhere && - happy && - thoughts && - somethingsomethingsomethingsomething - ) || ( - aa && - bb && - something && - elsewhere && - happy && - thoughts && - somethingsomethingsomethingsomething - ); + (aa && + bb && + something && + elsewhere && + happy && + thoughts && + somethingsomethingsomethingsomething) || + (aa && + bb && + something && + elsewhere && + happy && + thoughts && + somethingsomethingsomethingsomething); -( - lorem && // foo - ipsum -); +lorem && // foo + ipsum; -( - lorem && call_function(1, 3) // foo -); +lorem && + call_function( + 1, + 3, + ) // foo + ; -( - lorem && - // foo - (3 + 6 == 9) -); +lorem && + // foo + 3 + 6 == 9; let a = a || (b && c); @@ -313,13 +309,7 @@ a in LongClassName in LongClassName; -( - veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo instanceof String && veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar instanceof Number -) || veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar instanceof Boolean; - - -## Lines exceeding width of 80 characters - - 123: veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar - 190: veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo instanceof String && veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar instanceof Number +(veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo instanceof String && + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar instanceof Number) || + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar instanceof Boolean; diff --git a/crates/rome_js_formatter/tests/specs/js/module/object/property_object_member.js.snap b/crates/rome_js_formatter/tests/specs/js/module/object/property_object_member.js.snap index e3f8832353b..e8b12bf9c27 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/object/property_object_member.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/object/property_object_member.js.snap @@ -136,15 +136,16 @@ const breakAfterColonObject = { "logical-expression-2": longLongLongLongLongLongLongLongLongLongLongLongLongTooLongVar || 1337, "binary-expression-1": - 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132, + 13321321312312321311332132131231232131232132132132232132132132 + + 1332132131231232131232132132132, "binary-expression-2": - 1332132131231232131232132132132 - 13321321312312321312321321321321332132131231232131232132132132, + 1332132131231232131232132132132 - + 13321321312312321312321321321321332132131231232131232132132132, "instanceof-expression": "321321312312ddddddddddddddddddddddd312312312312" instanceof Object, "in-expression": - { - "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas", - } in "long-key", + { "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas" } in + "long-key", "sequence-expression": (33333333333333331, "dsadsadasdsadas", @@ -160,7 +161,8 @@ const breakAfterColonObject = { ? {} : {}, "conditional-expression-3": - 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 + 13321321312312321311332132131231232131232132132132232132132132 + + 1332132131231232131232132132132 ? {} : {}, "conditional-expression-4": @@ -168,24 +170,26 @@ const breakAfterColonObject = { ? {} : {}, "conditional-expression-5": - { - "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas", - } in "long-key", + { "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas" } in + "long-key", 1: this.state - .longLongLongLongLongLlongLongLongLongLongLongLongLongLongTooLongPropongLongLongLongTooLongProp === true, + .longLongLongLongLongLlongLongLongLongLongLongLongLongLongTooLongPropongLongLongLongTooLongProp === + true, 2: - longLongLongLongLongLongLongLongLonlongLongLongLongLongLongLongLongLongTooLongPropgLongLongLongLongTooLongVar || 1337, + longLongLongLongLongLongLongLongLonlongLongLongLongLongLongLongLongLongTooLongPropgLongLongLongLongTooLongVar || + 1337, 11: - 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132, + 13321321312312321311332132131231232131232132132132232132132132 + + 1332132131231232131232132132132, 22: - 1332132131231232131232132132132 - 13321321312312321312321321321321332132131231232131232132132132, + 1332132131231232131232132132132 - + 13321321312312321312321321321321332132131231232131232132132132, 33: "321321312312ddddddddddddddddddddddd312312312312" instanceof Object, 44: - { - "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas", - } in "long-key", + { "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas" } in + "long-key", 5: (33333333333333331, "dsadsadasdsadas", @@ -202,7 +206,8 @@ const breakAfterColonObject = { ? {} : {}, c: - 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 + 13321321312312321311332132131231232131232132132132232132132132 + + 1332132131231232131232132132132 ? {} : {}, d: @@ -210,9 +215,8 @@ const breakAfterColonObject = { ? {} : {}, g: - { - "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas", - } in "long-key", + { "long-key": "123123213123213123edwqdqwdasdasdsaewqewqewqdas" } in + "long-key", blablah: "aldkfkladfskladklsfkladklfkaldfadfkdaf" + "adlfasdklfkldsklfakldsfkladsfkadsfladsfa" + @@ -270,12 +274,6 @@ const fluidObject = { 18: number: 1232132132131231232132112321321321312312321321123213213213123123213211232132132131231232132112321321321312312321321, 19: "number-with-dot": 12321321321312312321321123213213213123123213211232132132131231232132112321321321312312321321.12321321321312312321321, 28: "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", - 36: 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132, - 38: 1332132131231232131232132132132 - 13321321312312321312321321321321332132131231232131232132132132, - 60: 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 - 74: .longLongLongLongLongLlongLongLongLongLongLongLongLongLongTooLongPropongLongLongLongTooLongProp === true, - 76: longLongLongLongLongLongLongLongLonlongLongLongLongLongLongLongLongLongTooLongPropgLongLongLongLongTooLongVar || 1337, - 78: 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132, - 80: 1332132131231232131232132132132 - 13321321312312321312321321321321332132131231232131232132132132, - 102: 13321321312312321311332132131231232131232132132132232132132132 + 1332132131231232131232132132132 + 75: .longLongLongLongLongLlongLongLongLongLongLongLongLongLongTooLongPropongLongLongLongTooLongProp === + 78: longLongLongLongLongLongLongLongLonlongLongLongLongLongLongLongLongLongTooLongPropgLongLongLongLongTooLongVar || diff --git a/crates/rome_js_formatter/tests/specs/js/module/parentheses/parentheses.js.snap b/crates/rome_js_formatter/tests/specs/js/module/parentheses/parentheses.js.snap index c601ffe04fd..ff2c3f826ce 100644 --- a/crates/rome_js_formatter/tests/specs/js/module/parentheses/parentheses.js.snap +++ b/crates/rome_js_formatter/tests/specs/js/module/parentheses/parentheses.js.snap @@ -54,12 +54,12 @@ const foo = { ...(a || b) }; async function* f() { await (a || b); - yield (a && b); + yield a && b; } -const a = () => (({})?.() && a); +const a = () => ({})?.() && a; -(list || list2)?.[(list || list2)]; +(list || list2)?.[list || list2]; ## Lines exceeding width of 80 characters diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/assignment-comments/string.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/assignment-comments/string.js.snap index 122b9435592..41d18942fb4 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/assignment-comments/string.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/assignment-comments/string.js.snap @@ -82,32 +82,9 @@ var fnString = // Comment ```diff --- Prettier +++ Rome -@@ -24,19 +24,20 @@ - - fnString = - /* inline */ "some" + -- "long" + -- "string" + -- "some" + -- "long" + -- "string" + -- "some" + -- "long" + -- "string" + -- "some" + -- "long" + -- "string"; -+ "long" + -+ "string" + -+ "some" + -+ "long" + -+ "string" + -+ "some" + -+ "long" + -+ "string" + -+ "some" + -+ "long" + -+ "string"; +@@ -36,7 +36,8 @@ + "long" + + "string"; -fnString = // Comment0 +fnString = @@ -156,17 +133,17 @@ fnString = fnString = /* inline */ "some" + - "long" + - "string" + - "some" + - "long" + - "string" + - "some" + - "long" + - "string" + - "some" + - "long" + - "string"; + "long" + + "string" + + "some" + + "long" + + "string" + + "some" + + "long" + + "string" + + "some" + + "long" + + "string"; fnString = // Comment0 diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/assignment/issue-2184.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/assignment/issue-2184.js.snap deleted file mode 100644 index f328c14db4f..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/assignment/issue-2184.js.snap +++ /dev/null @@ -1,45 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -const areaPercentageDiff = ( - topRankedZoneFit.areaPercentageRemaining - - previousZoneFitNow.areaPercentageRemaining -).toFixed(2) -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,4 +1,4 @@ --const areaPercentageDiff = ( -- topRankedZoneFit.areaPercentageRemaining - -- previousZoneFitNow.areaPercentageRemaining --).toFixed(2); -+const areaPercentageDiff = -+ (topRankedZoneFit.areaPercentageRemaining - previousZoneFitNow.areaPercentageRemaining).toFixed( -+ 2, -+ ); -``` - -# Output - -```js -const areaPercentageDiff = - (topRankedZoneFit.areaPercentageRemaining - previousZoneFitNow.areaPercentageRemaining).toFixed( - 2, - ); -``` - - -# Lines exceeding max width of 80 characters -``` - 2: (topRankedZoneFit.areaPercentageRemaining - previousZoneFitNow.areaPercentageRemaining).toFixed( -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/bigint.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/bigint.js.snap index d5af6f3e951..40b6a48aaa1 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/bigint.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/bigint.js.snap @@ -141,20 +141,18 @@ const alsoGoodPrecision = 9007199254740993n; ```diff --- Prettier +++ Rome -@@ -103,10 +103,10 @@ +@@ -103,9 +103,10 @@ 1n + 2; // ↪ TypeError: Cannot mix BigInt and other types, use explicit conversions -1n * 2 + -- // ↪ TypeError: Cannot mix BigInt and other types, use explicit conversions +1n * 2 -+// ↪ TypeError: Cannot mix BigInt and other types, use explicit conversions + // ↪ TypeError: Cannot mix BigInt and other types, use explicit conversions -- 1n; -++ 1n; ++ + + 1n; // ↪ TypeError: Cannot convert a BigInt value to a number - Number(1n); ``` # Output @@ -266,9 +264,10 @@ view[0]; // ↪ TypeError: Cannot mix BigInt and other types, use explicit conversions 1n * 2 -// ↪ TypeError: Cannot mix BigInt and other types, use explicit conversions + // ↪ TypeError: Cannot mix BigInt and other types, use explicit conversions -+ 1n; + + + 1n; // ↪ TypeError: Cannot convert a BigInt value to a number Number(1n); diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/arrow.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/arrow.js.snap deleted file mode 100644 index 8b7c5ca98de..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/arrow.js.snap +++ /dev/null @@ -1,75 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -function f() { - const appEntities = getAppEntities(loadObject).filter( - entity => entity && entity.isInstallAvailable() && !entity.isQueue() && entity.isDisabled() - ) -} - -function f2() { - const appEntities = getAppEntities(loadObject).map( - entity => entity && entity.isInstallAvailable() && !entity.isQueue() && entity.isDisabled() && { - id: entity.id - } - ) -} - -((x) => x) + ''; -'' + ((x) => x); -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -14,7 +14,8 @@ - entity && - entity.isInstallAvailable() && - !entity.isQueue() && -- entity.isDisabled() && { -+ entity.isDisabled() && -+ { - id: entity.id, - }, - ); -``` - -# Output - -```js -function f() { - const appEntities = getAppEntities(loadObject).filter( - (entity) => - entity && - entity.isInstallAvailable() && - !entity.isQueue() && - entity.isDisabled(), - ); -} - -function f2() { - const appEntities = getAppEntities(loadObject).map( - (entity) => - entity && - entity.isInstallAvailable() && - !entity.isQueue() && - entity.isDisabled() && - { - id: entity.id, - }, - ); -} - -((x) => x) + ""; -"" + ((x) => x); -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/call.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/call.js.snap deleted file mode 100644 index 91c6aeafdae..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/call.js.snap +++ /dev/null @@ -1,181 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee -)(); - -( - aa && - bb && - cc && - dd && - ee -)(); - -( - aaaaaaaaaaaaaaaaaaaaaaaaa + - bbbbbbbbbbbbbbbbbbbbbbbbb + - ccccccccccccccccccccccccc + - ddddddddddddddddddddddddd + - eeeeeeeeeeeeeeeeeeeeeeeee -)(); - -( - aa + - bb + - cc + - dd + - ee -)(); - -( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee -)()()(); - -( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee -)( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee -)( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee -)( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee -); -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,38 +1,30 @@ --( -- aaaaaaaaaaaaaaaaaaaaaaaaa && -+(aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && -- eeeeeeeeeeeeeeeeeeeeeeeee --)(); -+ eeeeeeeeeeeeeeeeeeeeeeeee)(); - - (aa && bb && cc && dd && ee)(); - --( -- aaaaaaaaaaaaaaaaaaaaaaaaa + -+(aaaaaaaaaaaaaaaaaaaaaaaaa + - bbbbbbbbbbbbbbbbbbbbbbbbb + - ccccccccccccccccccccccccc + - ddddddddddddddddddddddddd + -- eeeeeeeeeeeeeeeeeeeeeeeee --)(); -+ eeeeeeeeeeeeeeeeeeeeeeeee)(); - - (aa + bb + cc + dd + ee)(); - --( -- aaaaaaaaaaaaaaaaaaaaaaaaa && -+(aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && -- eeeeeeeeeeeeeeeeeeeeeeeee --)()()(); -+ eeeeeeeeeeeeeeeeeeeeeeeee)()()(); - --( -- aaaaaaaaaaaaaaaaaaaaaaaaa && -+(aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && -- eeeeeeeeeeeeeeeeeeeeeeeee --)( -+ eeeeeeeeeeeeeeeeeeeeeeeee)( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && -``` - -# Output - -```js -(aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee)(); - -(aa && bb && cc && dd && ee)(); - -(aaaaaaaaaaaaaaaaaaaaaaaaa + - bbbbbbbbbbbbbbbbbbbbbbbbb + - ccccccccccccccccccccccccc + - ddddddddddddddddddddddddd + - eeeeeeeeeeeeeeeeeeeeeeeee)(); - -(aa + bb + cc + dd + ee)(); - -(aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee)()()(); - -(aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee)( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee, -)( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee, -)( - aaaaaaaaaaaaaaaaaaaaaaaaa && - bbbbbbbbbbbbbbbbbbbbbbbbb && - ccccccccccccccccccccccccc && - ddddddddddddddddddddddddd && - eeeeeeeeeeeeeeeeeeeeeeeee, -); -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/comment.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/comment.js.snap deleted file mode 100644 index 74284fa7c7c..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/comment.js.snap +++ /dev/null @@ -1,173 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -a = ( - // Comment 1 - (Math.random() * (yRange * (1 - minVerticalFraction))) - + (minVerticalFraction * yRange) -) - offset; - -a + - a + - a + // comment - a + - a; - -a && - longLongLongLongLongLongLongLongLong && - longLongLongLongLongLongLongLongLong && // comment - longLongLongLongLongLongLongLongLong && - longLongLongLongLongLongLongLongLong - -a || - longLongLongLongLongLongLongLongLong || - longLongLongLongLongLongLongLongLong || // comment - longLongLongLongLongLongLongLongLong || - longLongLongLongLongLongLongLongLong - -var a = x(abifornCringerMoshedPerplexSawder -+ kochabCooieGameOnOboleUnweave // f -+ glimseGlyphsHazardNoopsTieTie+bifornCringerMoshedPerplexSawder); - -foo[ - a + - a + // comment - a + - bar[ - b + - b + - b + // comment - b + - b - ] -]; - -!( - a + - a + // comment - a + - !( - b + - b + - b + // comment - b + - b - ) -); -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,8 +1,10 @@ - a = -- // Comment 1 -- Math.random() * (yRange * (1 - minVerticalFraction)) + -- minVerticalFraction * yRange - -- offset; -+ ( -+ // Comment 1 -+ (Math.random() * (yRange * (1 - minVerticalFraction))) + ( -+ minVerticalFraction * yRange -+ ) -+ ) - offset; - - a + - a + -@@ -44,13 +46,13 @@ - - !( - a + -- a + // comment -- a + -- !( -- b + -- b + -- b + // comment -- b + -- b -- ) -+ a + // comment -+ a + -+ !( -+ b + -+ b + -+ b + // comment -+ b + -+ b -+ ) - ); -``` - -# Output - -```js -a = - ( - // Comment 1 - (Math.random() * (yRange * (1 - minVerticalFraction))) + ( - minVerticalFraction * yRange - ) - ) - offset; - -a + - a + - a + // comment - a + - a; - -a && - longLongLongLongLongLongLongLongLong && - longLongLongLongLongLongLongLongLong && // comment - longLongLongLongLongLongLongLongLong && - longLongLongLongLongLongLongLongLong; - -a || - longLongLongLongLongLongLongLongLong || - longLongLongLongLongLongLongLongLong || // comment - longLongLongLongLongLongLongLongLong || - longLongLongLongLongLongLongLongLong; - -var a = x( - abifornCringerMoshedPerplexSawder + - kochabCooieGameOnOboleUnweave + // f - glimseGlyphsHazardNoopsTieTie + - bifornCringerMoshedPerplexSawder, -); - -foo[ - a + - a + // comment - a + - bar[ - b + - b + - b + // comment - b + - b - ] -]; - -!( - a + - a + // comment - a + - !( - b + - b + - b + // comment - b + - b - ) -); -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/if.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/if.js.snap deleted file mode 100644 index e4c54683bab..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/if.js.snap +++ /dev/null @@ -1,68 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -if (this.hasPlugin("dynamicImports") && this.lookahead().type) {} - -if (this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft) {} - -if (this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right) {} - -if (VeryVeryVeryVeryVeryVeryVeryVeryLong === VeryVeryVeryVeryVeryVeryVeryVeryLong) { -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -2,14 +2,13 @@ - } - - if ( -- this.hasPlugin("dynamicImports") && -- this.lookahead().type === tt.parenLeft -+ this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft - ) { - } - - if ( -- this.hasPlugin("dynamicImports") && -- this.lookahead().type === tt.parenLeft.right -+ this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft -+ .right - ) { - } - -``` - -# Output - -```js -if (this.hasPlugin("dynamicImports") && this.lookahead().type) { -} - -if ( - this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft -) { -} - -if ( - this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft - .right -) { -} - -if ( - VeryVeryVeryVeryVeryVeryVeryVeryLong === VeryVeryVeryVeryVeryVeryVeryVeryLong -) { -} -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-jsx.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-jsx.js.snap index 36466030d0e..e3269f11a5e 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-jsx.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-jsx.js.snap @@ -20,58 +20,44 @@ const avatar2 = (hasAvatar || showPlaceholder) && - - --); -+const user = -+ renderedUser || ( -+
-+ ); ++
+ ); const user2 = -- renderedUser || -- (shouldRenderUser && ( + renderedUser || + (shouldRenderUser && ( -
- -
-- )); -+ renderedUser || ( -+ shouldRenderUser && ( -+
-+ ) -+ ); ++
+ )); const avatar = hasAvatar && ; - --const avatar2 = (hasAvatar || showPlaceholder) && ( -- --); -+const avatar2 = -+ (hasAvatar || showPlaceholder) && ; ``` # Output ```js -const user = - renderedUser || ( -
- ); +const user = renderedUser || ( +
+); const user2 = - renderedUser || ( - shouldRenderUser && ( -
- ) - ); + renderedUser || + (shouldRenderUser && ( +
+ )); const avatar = hasAvatar && ; -const avatar2 = - (hasAvatar || showPlaceholder) && ; +const avatar2 = (hasAvatar || showPlaceholder) && ( + +); ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-object-array.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-object-array.js.snap deleted file mode 100644 index 279a275a474..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/inline-object-array.js.snap +++ /dev/null @@ -1,293 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -prevState = prevState || { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: '', - selectedCatalog: null, -}; - -prevState = prevState || - defaultState || { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: '', - selectedCatalog: null, - }; - -prevState = prevState || - defaultState && { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: '', - selectedCatalog: null, - }; - -prevState = prevState || useDefault && defaultState || { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: '', - selectedCatalog: null, - }; - -this.steps = steps || [ - { - name: 'mock-module', - path: '/nux/mock-module', - }, -]; - -this.steps = steps || checkStep && [ - { - name: 'mock-module', - path: '/nux/mock-module', - }, -]; - -this.steps = steps && checkStep || [ - { - name: 'mock-module', - path: '/nux/mock-module', - }, -]; - -const create = () => { - const result = doSomething(); - return ( - shouldReturn && - result.ok && { - status: "ok", - createdAt: result.createdAt, - updatedAt: result.updatedAt - } - ); -} - -const create2 = () => { - const result = doSomething(); - return ( - shouldReturn && result.ok && result || { - status: "ok", - createdAt: result.createdAt, - updatedAt: result.updatedAt - } - ); -} - -const obj = { - state: shouldHaveState && - stateIsOK && { - loadState: LOADED, - opened: false - }, - loadNext: stateIsOK && hasNext || { - skipNext: true - }, - loaded: true -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -7,7 +7,8 @@ - }; - - prevState = prevState || -- defaultState || { -+ defaultState || -+ { - catalogs: [], - loadState: LOADED, - opened: false, -@@ -16,17 +17,19 @@ - }; - - prevState = -- prevState || -- (defaultState && { -- catalogs: [], -- loadState: LOADED, -- opened: false, -- searchQuery: "", -- selectedCatalog: null, -- }); -+ prevState || ( -+ defaultState && { -+ catalogs: [], -+ loadState: LOADED, -+ opened: false, -+ searchQuery: "", -+ selectedCatalog: null, -+ } -+ ); - - prevState = prevState || -- (useDefault && defaultState) || { -+ (useDefault && defaultState) || -+ { - catalogs: [], - loadState: LOADED, - opened: false, -@@ -42,13 +45,14 @@ - ]; - - this.steps = -- steps || -- (checkStep && [ -- { -- name: "mock-module", -- path: "/nux/mock-module", -- }, -- ]); -+ steps || ( -+ checkStep && [ -+ { -+ name: "mock-module", -+ path: "/nux/mock-module", -+ }, -+ ] -+ ); - - this.steps = (steps && checkStep) || [ - { -@@ -61,7 +65,8 @@ - const result = doSomething(); - return ( - shouldReturn && -- result.ok && { -+ result.ok && -+ { - status: "ok", - createdAt: result.createdAt, - updatedAt: result.updatedAt, -@@ -82,7 +87,8 @@ - - const obj = { - state: shouldHaveState && -- stateIsOK && { -+ stateIsOK && -+ { - loadState: LOADED, - opened: false, - }, -``` - -# Output - -```js -prevState = prevState || { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: "", - selectedCatalog: null, -}; - -prevState = prevState || - defaultState || - { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: "", - selectedCatalog: null, - }; - -prevState = - prevState || ( - defaultState && { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: "", - selectedCatalog: null, - } - ); - -prevState = prevState || - (useDefault && defaultState) || - { - catalogs: [], - loadState: LOADED, - opened: false, - searchQuery: "", - selectedCatalog: null, - }; - -this.steps = steps || [ - { - name: "mock-module", - path: "/nux/mock-module", - }, -]; - -this.steps = - steps || ( - checkStep && [ - { - name: "mock-module", - path: "/nux/mock-module", - }, - ] - ); - -this.steps = (steps && checkStep) || [ - { - name: "mock-module", - path: "/nux/mock-module", - }, -]; - -const create = () => { - const result = doSomething(); - return ( - shouldReturn && - result.ok && - { - status: "ok", - createdAt: result.createdAt, - updatedAt: result.updatedAt, - } - ); -}; - -const create2 = () => { - const result = doSomething(); - return ( - (shouldReturn && result.ok && result) || { - status: "ok", - createdAt: result.createdAt, - updatedAt: result.updatedAt, - } - ); -}; - -const obj = { - state: shouldHaveState && - stateIsOK && - { - loadState: LOADED, - opened: false, - }, - loadNext: (stateIsOK && hasNext) || { - skipNext: true, - }, - loaded: true, -}; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/jsx_parent.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/jsx_parent.js.snap index 93ae15244d2..5dd538f4034 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/jsx_parent.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/jsx_parent.js.snap @@ -46,42 +46,15 @@ source: crates/rome_js_formatter/tests/prettier_tests.rs ```diff --- Prettier +++ Rome -@@ -1,8 +1,8 @@ -
; - -@@ -15,25 +15,22 @@ -
; +@@ -24,16 +24,12 @@
-- {!isJellyfishEnabled && diffUpdateMessageInput != null && ( + {!isJellyfishEnabled && diffUpdateMessageInput != null && ( -
- Text -
-- )} -+ {!isJellyfishEnabled && -+ diffUpdateMessageInput != null && -+
Text
} ++
Text
+ )}
;
@@ -100,8 +73,8 @@ source: crates/rome_js_formatter/tests/prettier_tests.rs
; @@ -114,18 +87,17 @@ source: crates/rome_js_formatter/tests/prettier_tests.rs
;
- {!isJellyfishEnabled && - diffUpdateMessageInput != null && -
Text
} + {!isJellyfishEnabled && diffUpdateMessageInput != null && ( +
Text
+ )}
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/return.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/return.js.snap deleted file mode 100644 index 2c771d0a440..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/return.js.snap +++ /dev/null @@ -1,86 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -function foo() { - return this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right; -} - -function foo2() { - return this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right - ? true - : false; -} - -function foo3() { - return this.calculate().compute().first.numberOfThings > this.calculate().compute().last.numberOfThings - ? true - : false; -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,20 +1,20 @@ - function foo() { - return ( -- this.hasPlugin("dynamicImports") && -- this.lookahead().type === tt.parenLeft.right -+ this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft -+ .right - ); - } - - function foo2() { -- return this.hasPlugin("dynamicImports") && -- this.lookahead().type === tt.parenLeft.right -+ return this.hasPlugin("dynamicImports") && this.lookahead().type === tt -+ .parenLeft.right - ? true - : false; - } - - function foo3() { -- return this.calculate().compute().first.numberOfThings > -- this.calculate().compute().last.numberOfThings -+ return this.calculate().compute().first -+ .numberOfThings > this.calculate().compute().last.numberOfThings - ? true - : false; - } -``` - -# Output - -```js -function foo() { - return ( - this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft - .right - ); -} - -function foo2() { - return this.hasPlugin("dynamicImports") && this.lookahead().type === tt - .parenLeft.right - ? true - : false; -} - -function foo3() { - return this.calculate().compute().first - .numberOfThings > this.calculate().compute().last.numberOfThings - ? true - : false; -} -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/short-right.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/short-right.js.snap deleted file mode 100644 index 6f00fe50b8d..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/short-right.js.snap +++ /dev/null @@ -1,73 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -this._cumulativeHeights && - Math.abs( - this._cachedItemHeight(this._firstVisibleIndex + i) - - this._provider.fastHeight(i + this._firstVisibleIndex), - ) > - 1 - -foooooooooooooooooooooooooooooooooooooooooooooooooooooooooo( - aaaaaaaaaaaaaaaaaaa -) + - a; - -const isPartOfPackageJSON = dependenciesArray.indexOf( - dependencyWithOutRelativePath.split('/')[0], -) !== -1; - -defaultContent.filter(defaultLocale => { - // ... -})[0] || null; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,8 +1,8 @@ --this._cumulativeHeights && -- Math.abs( -- this._cachedItemHeight(this._firstVisibleIndex + i) - -- this._provider.fastHeight(i + this._firstVisibleIndex), -- ) > 1; -+this._cumulativeHeights && Math.abs( -+ this._cachedItemHeight( -+ this._firstVisibleIndex + i, -+ ) - this._provider.fastHeight(i + this._firstVisibleIndex), -+) > 1; - - foooooooooooooooooooooooooooooooooooooooooooooooooooooooooo( - aaaaaaaaaaaaaaaaaaa, -``` - -# Output - -```js -this._cumulativeHeights && Math.abs( - this._cachedItemHeight( - this._firstVisibleIndex + i, - ) - this._provider.fastHeight(i + this._firstVisibleIndex), -) > 1; - -foooooooooooooooooooooooooooooooooooooooooooooooooooooooooo( - aaaaaaaaaaaaaaaaaaa, -) + a; - -const isPartOfPackageJSON = - dependenciesArray.indexOf(dependencyWithOutRelativePath.split("/")[0]) !== -1; - -defaultContent.filter((defaultLocale) => { - // ... -})[0] || null; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/unary.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/unary.js.snap deleted file mode 100644 index 220458088b0..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary-expressions/unary.js.snap +++ /dev/null @@ -1,41 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -const anyTestFailures = !( - aggregatedResults.numFailedTests === 0 && - aggregatedResults.numRuntimeErrorTestSuites === 0 -); -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,4 +1,3 @@ - const anyTestFailures = !( -- aggregatedResults.numFailedTests === 0 && -- aggregatedResults.numRuntimeErrorTestSuites === 0 -+ aggregatedResults.numFailedTests === 0 && aggregatedResults.numRuntimeErrorTestSuites === 0 - ); -``` - -# Output - -```js -const anyTestFailures = !( - aggregatedResults.numFailedTests === 0 && aggregatedResults.numRuntimeErrorTestSuites === 0 -); -``` - - -# Lines exceeding max width of 80 characters -``` - 2: aggregatedResults.numFailedTests === 0 && aggregatedResults.numRuntimeErrorTestSuites === 0 -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/binary_math/parens.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/binary_math/parens.js.snap deleted file mode 100644 index f3c3705d995..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/binary_math/parens.js.snap +++ /dev/null @@ -1,74 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -const result = (a + b) >>> 1; -var sizeIndex = ((index - 1) >>> level) & MASK; -var from = offset > left ? 0 : (left - offset) >> level; -var to = ((right - offset) >> level) + 1; -if (rawIndex < 1 << (list._level + SHIFT)) {} -var res = size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); -sign = 1 - (2 * (b[3] >> 7)); -exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127; -mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0]; - -2 / 3 * 10 / 2 + 2; -const rotateX = ((RANGE / rect.height) * refY - RANGE / 2) * getXMultiplication(rect.width); -const rotateY = ((RANGE / rect.width) * refX - RANGE / 2) * getYMultiplication(rect.width); - -a % 10 - 5; -a * b % 10; -a % 10 > 5; -a % 10 == 0; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -4,8 +4,8 @@ - var to = ((right - offset) >> level) + 1; - if (rawIndex < 1 << (list._level + SHIFT)) { - } --var res = size < SIZE ? 0 : ((size - 1) >>> SHIFT) << SHIFT; --sign = 1 - 2 * (b[3] >> 7); -+var res = size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); -+sign = 1 - (2 * (b[3] >> 7)); - exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127; - mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0]; - -``` - -# Output - -```js -const result = (a + b) >>> 1; -var sizeIndex = ((index - 1) >>> level) & MASK; -var from = offset > left ? 0 : (left - offset) >> level; -var to = ((right - offset) >> level) + 1; -if (rawIndex < 1 << (list._level + SHIFT)) { -} -var res = size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); -sign = 1 - (2 * (b[3] >> 7)); -exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127; -mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0]; - -((2 / 3) * 10) / 2 + 2; -const rotateX = - ((RANGE / rect.height) * refY - RANGE / 2) * getXMultiplication(rect.width); -const rotateY = - ((RANGE / rect.width) * refX - RANGE / 2) * getYMultiplication(rect.width); - -(a % 10) - 5; -(a * b) % 10; -a % 10 > 5; -a % 10 == 0; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/bind-expressions/bind_parens.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/bind-expressions/bind_parens.js.snap index fc71e6b9d48..59d21316b76 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/bind-expressions/bind_parens.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/bind-expressions/bind_parens.js.snap @@ -79,7 +79,7 @@ f[a::b()]; -(b.c::d).e; -(b::c::d).e; -new (a::b)(); -+(a || b); ++a || b; +::c +a || (b +::c) @@ -152,7 +152,7 @@ f[a::b()]; # Output ```js -(a || b); +a || b; ::c a || (b ::c) diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/class-comment/class-property.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/class-comment/class-property.js.snap deleted file mode 100644 index 41adf422286..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/class-comment/class-property.js.snap +++ /dev/null @@ -1,47 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -class X { - TEMPLATE = - // tab index is needed so we can focus, which is needed for keyboard events - '
' + - '
' + - '
'; -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -2,6 +2,6 @@ - TEMPLATE = - // tab index is needed so we can focus, which is needed for keyboard events - '
' + -- '
' + -- "
"; -+ '
' + -+ "
"; - } -``` - -# Output - -```js -class X { - TEMPLATE = - // tab index is needed so we can focus, which is needed for keyboard events - '
' + - '
' + - "
"; -} -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/classes-private-fields/with_comments.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/classes-private-fields/with_comments.js.snap deleted file mode 100644 index 3248261ad10..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/classes-private-fields/with_comments.js.snap +++ /dev/null @@ -1,47 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -class A { - #foobar = - // comment to break - 1 + - // comment to break again - 2; -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -2,6 +2,6 @@ - #foobar = - // comment to break - 1 + -- // comment to break again -- 2; -+ // comment to break again -+ 2; - } -``` - -# Output - -```js -class A { - #foobar = - // comment to break - 1 + - // comment to break again - 2; -} -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/classes/property.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/classes/property.js.snap deleted file mode 100644 index 7e85f6ffab9..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/classes/property.js.snap +++ /dev/null @@ -1,71 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -class A { - foobar = - // comment to break - 1 + - // comment to break again - 2; -} - -class B { - someInstanceProperty = this.props.foofoofoofoofoofoo && - this.props.barbarbarbar; - - someInstanceProperty2 = { foo: this.props.foofoofoofoofoofoo && - this.props.barbarbarbar }; - - someInstanceProperty3 = - "foo"; -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -2,8 +2,8 @@ - foobar = - // comment to break - 1 + -- // comment to break again -- 2; -+ // comment to break again -+ 2; - } - - class B { -``` - -# Output - -```js -class A { - foobar = - // comment to break - 1 + - // comment to break again - 2; -} - -class B { - someInstanceProperty = - this.props.foofoofoofoofoofoo && this.props.barbarbarbar; - - someInstanceProperty2 = { - foo: this.props.foofoofoofoofoofoo && this.props.barbarbarbar, - }; - - someInstanceProperty3 = "foo"; -} -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/binary-expr.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/binary-expr.js.snap index 77737960ee3..b14dc3f4a22 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/binary-expr.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/binary-expr.js.snap @@ -15,19 +15,15 @@ var a = b || /** @type {string} */ ```diff --- Prettier +++ Rome -@@ -1 +1,3 @@ +@@ -1 +1 @@ -var a = b || /** @type {string} */ (c); -+var a = -+ b || /** @type {string} */ -+ c; ++var a = b || /** @type {string} */ c; ``` # Output ```js -var a = - b || /** @type {string} */ - c; +var a = b || /** @type {string} */ c; ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/closure-compiler-type-cast.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/closure-compiler-type-cast.js.snap index 2067797fcd1..bfeea10da12 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/closure-compiler-type-cast.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/closure-compiler-type-cast.js.snap @@ -73,7 +73,7 @@ const style2 =/** ```diff --- Prettier +++ Rome -@@ -9,35 +9,39 @@ +@@ -9,35 +9,35 @@ }; // preserve parens only for type casts @@ -83,11 +83,7 @@ const style2 =/** +let value = /** @type {string} */ this.members[0].functionCall(); -functionCall(1 + /** @type {string} */ (value), /** @type {!Foo} */ ({})); -+functionCall( -+ 1 + /** @type {string} */ -+ value, /** @type {!Foo} */ -+ {}, -+); ++functionCall(1 + /** @type {string} */ value, /** @type {!Foo} */ {}); function returnValue() { - return /** @type {!Array.} */ (["hello", "you"]); @@ -129,7 +125,7 @@ const style2 =/** ); const style = /** @type {{ -@@ -47,16 +51,16 @@ +@@ -47,16 +47,16 @@ marginLeft: number, marginRight: number, marginBottom: number, @@ -169,11 +165,7 @@ let object = { let assignment = /** @type {string} */ getValue(); let value = /** @type {string} */ this.members[0].functionCall(); -functionCall( - 1 + /** @type {string} */ - value, /** @type {!Foo} */ - {}, -); +functionCall(1 + /** @type {string} */ value, /** @type {!Foo} */ {}); function returnValue() { return /** @type {!Array.} */ ["hello", "you"]; diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/issue-9358.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/issue-9358.js.snap index f32b0548005..36b5e1881cd 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/issue-9358.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments-closure-typecast/issue-9358.js.snap @@ -16,34 +16,35 @@ const fooooba3 = /** @type {Array.} */ (fooobaarbazzItems || ```diff --- Prettier +++ Rome -@@ -1,9 +1,7 @@ +@@ -1,11 +1,6 @@ -const fooooba1 = /** @type {Array.} */ ( - fooobaarbazzItems || foo -); -const fooooba2 = /** @type {Array.} */ ( - fooobaarbazzItems + foo -); +-const fooooba3 = /** @type {Array.} */ ( +- fooobaarbazzItems || foo +-) +- ? foo +- : bar; +const fooooba1 = /** @type {Array.} */ -+ (fooobaarbazzItems || foo); ++ fooobaarbazzItems || foo; +const fooooba2 = /** @type {Array.} */ -+ (fooobaarbazzItems + foo); - const fooooba3 = /** @type {Array.} */ ( - fooobaarbazzItems || foo - ) ++ fooobaarbazzItems + foo; ++const fooooba3 = /** @type {Array.} */ ++ fooobaarbazzItems || foo ? foo : bar; ``` # Output ```js const fooooba1 = /** @type {Array.} */ - (fooobaarbazzItems || foo); + fooobaarbazzItems || foo; const fooooba2 = /** @type {Array.} */ - (fooobaarbazzItems + foo); -const fooooba3 = /** @type {Array.} */ ( - fooobaarbazzItems || foo -) - ? foo - : bar; + fooobaarbazzItems + foo; +const fooooba3 = /** @type {Array.} */ + fooobaarbazzItems || foo ? foo : bar; ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-block-comments.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-block-comments.js.snap index 4afff0a6129..03cf52e33b0 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-block-comments.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-block-comments.js.snap @@ -53,11 +53,9 @@ a = b + /** TODO this is a very very very very long comment that makes it go > 8 ```diff --- Prettier +++ Rome -@@ -1,47 +1,50 @@ +@@ -1,9 +1,9 @@ -a = b /** Comment */ || c; -+a = -+ b || /** Comment */ -+ c; ++a = b || /** Comment */ c; a = b /** Comment */ || c; @@ -67,44 +65,38 @@ a = b + /** TODO this is a very very very very long comment that makes it go > 8 c; a = -- b /** TODO this is a very very very very long comment that makes it go > 80 columns */ || -+ b /** TODO this is a very very very very long comment that makes it go > 80 columns */ || c; -+ -+a = -+ b || /** TODO this is a very very very very long comment that makes it go > 80 columns */ +@@ -11,15 +11,15 @@ c; a = - b || - /** TODO this is a very very very very long comment that makes it go > 80 columns */ c; -+ b && /** Comment */ ++ b || /** TODO this is a very very very very long comment that makes it go > 80 columns */ + c; +-a = b /** Comment */ && c; ++a = b && /** Comment */ c; + a = b /** Comment */ && c; --a = b /** Comment */ && c; -- a = - b /** TODO this is a very very very very long comment that makes it go > 80 columns */ && + b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ c; a = -- b /** TODO this is a very very very very long comment that makes it go > 80 columns */ && -+ b /** TODO this is a very very very very long comment that makes it go > 80 columns */ && c; -+ -+a = -+ b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ +@@ -27,15 +27,15 @@ c; a = - b && - /** TODO this is a very very very very long comment that makes it go > 80 columns */ c; -- --a = b /** Comment */ + c; -+ b + /** Comment */ ++ b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ + c; +-a = b /** Comment */ + c; ++a = b + /** Comment */ c; + a = b /** Comment */ + c; a = @@ -113,9 +105,8 @@ a = b + /** TODO this is a very very very very long comment that makes it go > 8 c; a = -- b /** TODO this is a very very very very long comment that makes it go > 80 columns */ + -- c; -+ b /** TODO this is a very very very very long comment that makes it go > 80 columns */ + c; +@@ -43,5 +43,5 @@ + c; a = - b + @@ -127,9 +118,7 @@ a = b + /** TODO this is a very very very very long comment that makes it go > 8 # Output ```js -a = - b || /** Comment */ - c; +a = b || /** Comment */ c; a = b /** Comment */ || c; @@ -138,15 +127,14 @@ a = c; a = - b /** TODO this is a very very very very long comment that makes it go > 80 columns */ || c; + b /** TODO this is a very very very very long comment that makes it go > 80 columns */ || + c; a = b || /** TODO this is a very very very very long comment that makes it go > 80 columns */ c; -a = - b && /** Comment */ - c; +a = b && /** Comment */ c; a = b /** Comment */ && c; @@ -155,15 +143,14 @@ a = c; a = - b /** TODO this is a very very very very long comment that makes it go > 80 columns */ && c; + b /** TODO this is a very very very very long comment that makes it go > 80 columns */ && + c; a = b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ c; -a = - b + /** Comment */ - c; +a = b + /** Comment */ c; a = b /** Comment */ + c; @@ -172,7 +159,8 @@ a = c; a = - b /** TODO this is a very very very very long comment that makes it go > 80 columns */ + c; + b /** TODO this is a very very very very long comment that makes it go > 80 columns */ + + c; a = b + /** TODO this is a very very very very long comment that makes it go > 80 columns */ @@ -182,14 +170,14 @@ a = # Lines exceeding max width of 80 characters ``` - 8: b || /** TODO this is a very very very very long comment that makes it go > 80 columns */ - 12: b /** TODO this is a very very very very long comment that makes it go > 80 columns */ || c; - 15: b || /** TODO this is a very very very very long comment that makes it go > 80 columns */ - 25: b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ - 29: b /** TODO this is a very very very very long comment that makes it go > 80 columns */ && c; - 32: b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ - 42: b + /** TODO this is a very very very very long comment that makes it go > 80 columns */ - 46: b /** TODO this is a very very very very long comment that makes it go > 80 columns */ + c; - 49: b + /** TODO this is a very very very very long comment that makes it go > 80 columns */ + 6: b || /** TODO this is a very very very very long comment that makes it go > 80 columns */ + 10: b /** TODO this is a very very very very long comment that makes it go > 80 columns */ || + 14: b || /** TODO this is a very very very very long comment that makes it go > 80 columns */ + 22: b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ + 26: b /** TODO this is a very very very very long comment that makes it go > 80 columns */ && + 30: b && /** TODO this is a very very very very long comment that makes it go > 80 columns */ + 38: b + /** TODO this is a very very very very long comment that makes it go > 80 columns */ + 42: b /** TODO this is a very very very very long comment that makes it go > 80 columns */ + + 46: b + /** TODO this is a very very very very long comment that makes it go > 80 columns */ ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-parens.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-parens.js.snap index 2343d41ff74..5eb92b14cc6 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-parens.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions-parens.js.snap @@ -23,34 +23,28 @@ Math.min( ```diff --- Prettier +++ Rome -@@ -1,9 +1,9 @@ +@@ -1,7 +1,7 @@ Math.min( -- /* $FlowFixMe(>=0.38.0 site=www) - Flow error detected during the + /* $FlowFixMe(>=0.38.0 site=www) - Flow error detected during the - * deployment of v0.38.0. To see the error, remove this comment and - * run flow */ -- document.body.scrollHeight - -- (window.scrollY + window.innerHeight) - -- devsite_footer_height, -+ ( -+ /* $FlowFixMe(>=0.38.0 site=www) - Flow error detected during the + * deployment of v0.38.0. To see the error, remove this comment and + * run flow */ -+ document.body.scrollHeight - (window.scrollY + window.innerHeight) -+ ) - devsite_footer_height, - 0, - ); + document.body.scrollHeight - + (window.scrollY + window.innerHeight) - + devsite_footer_height, ``` # Output ```js Math.min( - ( - /* $FlowFixMe(>=0.38.0 site=www) - Flow error detected during the + /* $FlowFixMe(>=0.38.0 site=www) - Flow error detected during the * deployment of v0.38.0. To see the error, remove this comment and * run flow */ - document.body.scrollHeight - (window.scrollY + window.innerHeight) - ) - devsite_footer_height, + document.body.scrollHeight - + (window.scrollY + window.innerHeight) - + devsite_footer_height, 0, ); ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions.js.snap index 0eaf1120bb2..b3bcd2411f5 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments/binary-expressions.js.snap @@ -84,113 +84,101 @@ function bitwiseXor() { ```diff --- Prettier +++ Rome -@@ -1,71 +1,71 @@ +@@ -1,71 +1,83 @@ function addition() { - 0 + -- // Comment -- x; + 0 -+ // Comment -+ + x; + // Comment ++ + + x; } function multiplication() { - 0 * -- // Comment -- x; + 0 -+ // Comment -+ * x; + // Comment ++ * + x; } function division() { - 0 / -- // Comment -- x; + 0 -+ // Comment -+ / x; + // Comment ++ / + x; } function substraction() { - 0 - -- // Comment -- x; + 0 -+ // Comment -+ - x; + // Comment ++ - + x; } function remainder() { - 0 % -- // Comment -- x; + 0 -+ // Comment -+ % x; + // Comment ++ % + x; } function exponentiation() { - 0 ** -- // Comment -- x; + 0 -+ // Comment -+ ** x; + // Comment ++ ** + x; } function leftShift() { - 0 << -- // Comment -- x; + 0 -+ // Comment -+ << x; + // Comment ++ << + x; } function rightShift() { - 0 >> -- // Comment -- x; + 0 -+ // Comment -+ >> x; + // Comment ++ >> + x; } function unsignedRightShift() { - 0 >>> -- // Comment -- x; + 0 -+ // Comment -+ >>> x; + // Comment ++ >>> + x; } function bitwiseAnd() { - 0 & -- // Comment -- x; + 0 -+ // Comment -+ & x; + // Comment ++ & + x; } function bitwiseOr() { - 0 | -- // Comment -- x; + 0 -+ // Comment -+ | x; + // Comment ++ | + x; } function bitwiseXor() { - 0 ^ -- // Comment -- x; + 0 -+ // Comment -+ ^ x; + // Comment ++ ^ + x; } ``` @@ -199,74 +187,86 @@ function bitwiseXor() { ```js function addition() { 0 - // Comment - + x; + // Comment + + + x; } function multiplication() { 0 - // Comment - * x; + // Comment + * + x; } function division() { 0 - // Comment - / x; + // Comment + / + x; } function substraction() { 0 - // Comment - - x; + // Comment + - + x; } function remainder() { 0 - // Comment - % x; + // Comment + % + x; } function exponentiation() { 0 - // Comment - ** x; + // Comment + ** + x; } function leftShift() { 0 - // Comment - << x; + // Comment + << + x; } function rightShift() { 0 - // Comment - >> x; + // Comment + >> + x; } function unsignedRightShift() { 0 - // Comment - >>> x; + // Comment + >>> + x; } function bitwiseAnd() { 0 - // Comment - & x; + // Comment + & + x; } function bitwiseOr() { 0 - // Comment - | x; + // Comment + | + x; } function bitwiseXor() { 0 - // Comment - ^ x; + // Comment + ^ + x; } ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap index 6d32a97c982..5ab99aaa8b2 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap @@ -36,7 +36,7 @@ while(1) // Comment ```diff --- Prettier +++ Rome -@@ -3,19 +3,14 @@ +@@ -3,15 +3,11 @@ // Comment ) {} @@ -53,12 +53,7 @@ while(1) // Comment +while (true) /*Comment*/ {} while ( -- true && // Comment -- true // Comment -+ true && true // Comment // Comment - ) {} - - while (true) {} // comment + true && // Comment ``` # Output @@ -76,7 +71,8 @@ while (true) {} // Comment while (true) /*Comment*/ {} while ( - true && true // Comment // Comment + true && // Comment + true // Comment ) {} while (true) {} // comment diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/function/function_expression.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/function/function_expression.js.snap index 52bfc70eec5..da6cd76eff5 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/function/function_expression.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/function/function_expression.js.snap @@ -35,7 +35,7 @@ new function() {}; (function () {}); a = function f() {} || b; -(function () {} && a); -+((function () {}) && a); ++(function () {}) && a; a + function () {}; new (function () {})(); ``` @@ -51,7 +51,7 @@ export default (function () {})(); new (function () {})(); (function () {}); a = function f() {} || b; -((function () {}) && a); +(function () {}) && a; a + function () {}; new (function () {})(); ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/issue-7024.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/issue-7024.js.snap index d9f054fd441..7f5a56432c2 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/issue-7024.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/issue-7024.js.snap @@ -17,28 +17,22 @@ const radioSelectedAttr = ```diff --- Prettier +++ Rome -@@ -1,5 +1,6 @@ +@@ -1,5 +1,4 @@ const radioSelectedAttr = -- (isAnyValueSelected && -- node.getAttribute(radioAttr.toLowerCase()) === radioValue) || + (isAnyValueSelected && + node.getAttribute(radioAttr.toLowerCase()) === radioValue) || - (!isAnyValueSelected && values[a].default === true) || - a === 0; -+ ( -+ isAnyValueSelected && node.getAttribute( -+ radioAttr.toLowerCase(), -+ ) === radioValue -+ ) || ((!isAnyValueSelected && values[a].default === true) || a === 0); ++ ((!isAnyValueSelected && values[a].default === true) || a === 0); ``` # Output ```js const radioSelectedAttr = - ( - isAnyValueSelected && node.getAttribute( - radioAttr.toLowerCase(), - ) === radioValue - ) || ((!isAnyValueSelected && values[a].default === true) || a === 0); + (isAnyValueSelected && + node.getAttribute(radioAttr.toLowerCase()) === radioValue) || + ((!isAnyValueSelected && values[a].default === true) || a === 0); ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/logical_expression_operators.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/logical_expression_operators.js.snap index 3b851159dab..617b0c8a80d 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/logical_expression_operators.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/logical_expressions/logical_expression_operators.js.snap @@ -47,43 +47,40 @@ foo || bar && baz; +++ Rome @@ -1,24 +1,24 @@ // Same operators do not require parens --foo && bar && baz; + foo && bar && baz; -foo && bar && baz; -foo && bar && baz && qux; -foo && bar && baz && qux; -foo && bar && baz && qux && xyz; -foo && bar && baz && qux && xyz; -+(foo && bar) && baz; +foo && (bar && baz); -+foo && ((bar && baz) && qux); ++foo && (bar && baz && qux); +foo && (bar && (baz && qux)); -+foo && (bar && ((baz && qux) && xyz)); ++foo && (bar && (baz && qux && xyz)); +foo && (bar && (baz && (qux && xyz))); --foo || bar || baz; + foo || bar || baz; -foo || bar || baz; -foo || bar || baz || qux; -foo || bar || baz || qux; -foo || bar || baz || qux || xyz; -foo || bar || baz || qux || xyz; -+(foo || bar) || baz; +foo || (bar || baz); -+foo || ((bar || baz) || qux); ++foo || (bar || baz || qux); +foo || (bar || (baz || qux)); -+foo || (bar || ((baz || qux) || xyz)); ++foo || (bar || (baz || qux || xyz)); +foo || (bar || (baz || (qux || xyz))); -foo ?? bar ?? baz; --foo ?? bar ?? baz; + foo ?? bar ?? baz; -foo ?? bar ?? baz ?? qux; -foo ?? bar ?? baz ?? qux; -foo ?? bar ?? baz ?? qux ?? xyz; -foo ?? bar ?? baz ?? qux ?? xyz; -+(foo ?? bar) ?? baz; +foo ?? (bar ?? baz); -+foo ?? ((bar ?? baz) ?? qux); ++foo ?? (bar ?? baz ?? qux); +foo ?? (bar ?? (baz ?? qux)); -+foo ?? (bar ?? ((baz ?? qux) ?? xyz)); ++foo ?? (bar ?? (baz ?? qux ?? xyz)); +foo ?? (bar ?? (baz ?? (qux ?? xyz))); // Explicitly parenthesized && and || requires parens @@ -94,25 +91,25 @@ foo || bar && baz; ```js // Same operators do not require parens -(foo && bar) && baz; +foo && bar && baz; foo && (bar && baz); -foo && ((bar && baz) && qux); +foo && (bar && baz && qux); foo && (bar && (baz && qux)); -foo && (bar && ((baz && qux) && xyz)); +foo && (bar && (baz && qux && xyz)); foo && (bar && (baz && (qux && xyz))); -(foo || bar) || baz; +foo || bar || baz; foo || (bar || baz); -foo || ((bar || baz) || qux); +foo || (bar || baz || qux); foo || (bar || (baz || qux)); -foo || (bar || ((baz || qux) || xyz)); +foo || (bar || (baz || qux || xyz)); foo || (bar || (baz || (qux || xyz))); -(foo ?? bar) ?? baz; +foo ?? bar ?? baz; foo ?? (bar ?? baz); -foo ?? ((bar ?? baz) ?? qux); +foo ?? (bar ?? baz ?? qux); foo ?? (bar ?? (baz ?? qux)); -foo ?? (bar ?? ((baz ?? qux) ?? xyz)); +foo ?? (bar ?? (baz ?? qux ?? xyz)); foo ?? (bar ?? (baz ?? (qux ?? xyz))); // Explicitly parenthesized && and || requires parens diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/member/logical.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/member/logical.js.snap deleted file mode 100644 index ee8ab7a8418..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/member/logical.js.snap +++ /dev/null @@ -1,43 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -(veryLongVeryLongVeryLong || e).prop; - -(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).prop; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -2,6 +2,6 @@ - - ( - veryLongVeryLongVeryLong || -- anotherVeryLongVeryLongVeryLong || -- veryVeryVeryLongError -+ anotherVeryLongVeryLongVeryLong || -+ veryVeryVeryLongError - ).prop; -``` - -# Output - -```js -(veryLongVeryLongVeryLong || e).prop; - -( - veryLongVeryLongVeryLong || - anotherVeryLongVeryLongVeryLong || - veryVeryVeryLongError -).prop; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/method-chain/logical.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/method-chain/logical.js.snap index 42557a0f90d..a487a31ffa5 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/method-chain/logical.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/method-chain/logical.js.snap @@ -30,14 +30,9 @@ const someLongVariableName = (idx( ```diff --- Prettier +++ Rome -@@ -1,25 +1,24 @@ --const someLongVariableName = ( -- idx(this.props, (props) => props.someLongPropertyName) || [] --).map((edge) => edge.node); -+const someLongVariableName = (idx( -+ this.props, -+ (props) => props.someLongPropertyName, -+) || []).map((edge) => edge.node); +@@ -2,13 +2,13 @@ + idx(this.props, (props) => props.someLongPropertyName) || [] + ).map((edge) => edge.node); -(veryLongVeryLongVeryLong || e).map((tickets) => - TicketRecord.createFromSomeLongString(), @@ -52,36 +47,26 @@ const someLongVariableName = (idx( + (tickets) => TicketRecord.createFromSomeLongString(), +).filter((obj) => !!obj); --( -- veryLongVeryLongVeryLong || -+(veryLongVeryLongVeryLong || + ( + veryLongVeryLongVeryLong || +@@ -20,6 +20,6 @@ + veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || -- veryVeryVeryLongError --).map((tickets) => TicketRecord.createFromSomeLongString()); -+ veryVeryVeryLongError).map( -+ (tickets) => TicketRecord.createFromSomeLongString(), -+); - --( -- veryLongVeryLongVeryLong || -+(veryLongVeryLongVeryLong || - anotherVeryLongVeryLongVeryLong || -- veryVeryVeryLongError + veryVeryVeryLongError -) - .map((tickets) => TicketRecord.createFromSomeLongString()) - .filter((obj) => !!obj); -+ veryVeryVeryLongError).map( -+ (tickets) => TicketRecord.createFromSomeLongString(), -+).filter((obj) => !!obj); ++).map((tickets) => TicketRecord.createFromSomeLongString()).filter( ++ (obj) => !!obj, ++); ``` # Output ```js -const someLongVariableName = (idx( - this.props, - (props) => props.someLongPropertyName, -) || []).map((edge) => edge.node); +const someLongVariableName = ( + idx(this.props, (props) => props.someLongPropertyName) || [] +).map((edge) => edge.node); (veryLongVeryLongVeryLong || e).map( (tickets) => TicketRecord.createFromSomeLongString(), @@ -91,17 +76,19 @@ const someLongVariableName = (idx( (tickets) => TicketRecord.createFromSomeLongString(), ).filter((obj) => !!obj); -(veryLongVeryLongVeryLong || +( + veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || - veryVeryVeryLongError).map( - (tickets) => TicketRecord.createFromSomeLongString(), -); + veryVeryVeryLongError +).map((tickets) => TicketRecord.createFromSomeLongString()); -(veryLongVeryLongVeryLong || +( + veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || - veryVeryVeryLongError).map( - (tickets) => TicketRecord.createFromSomeLongString(), -).filter((obj) => !!obj); + veryVeryVeryLongError +).map((tickets) => TicketRecord.createFromSomeLongString()).filter( + (obj) => !!obj, +); ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/multiparser-css/styled-components.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/multiparser-css/styled-components.js.snap index 60e4754dc85..085a19e1672 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/multiparser-css/styled-components.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/multiparser-css/styled-components.js.snap @@ -404,44 +404,13 @@ const StyledDiv = styled.div` `; const Single2 = styled.div` -@@ -199,8 +197,7 @@ - width: 40px; - +@@ -232,9 +230,9 @@ ${(props) => -- (props.complete || props.inProgress) && -- css` -+ (props.complete || props.inProgress) && css` - border-color: rgba(var(--green-rgb), 0.15); - `} - -@@ -212,15 +209,13 @@ - display: inline-flex; - - ${(props) => -- props.complete && -- css` -+ props.complete && css` - background-color: var(--green); - border-width: 7px; - `} - - ${(props) => -- (props.complete || props.inProgress) && -- css` -+ (props.complete || props.inProgress) && css` - border-color: var(--green); - `} - } -@@ -230,11 +225,10 @@ - display: inline-block; - color: #fff; - ${(props) => -- props.a && -- css` + props.a && + css` - display: none; - `} - height: 30px; -+ props.a && css` + display: none; + `} + height: 30px; @@ -652,7 +621,8 @@ const bar = styled.div` width: 40px; ${(props) => - (props.complete || props.inProgress) && css` + (props.complete || props.inProgress) && + css` border-color: rgba(var(--green-rgb), 0.15); `} @@ -664,13 +634,15 @@ const bar = styled.div` display: inline-flex; ${(props) => - props.complete && css` + props.complete && + css` background-color: var(--green); border-width: 7px; `} ${(props) => - (props.complete || props.inProgress) && css` + (props.complete || props.inProgress) && + css` border-color: var(--green); `} } @@ -680,7 +652,8 @@ const A = styled.a` display: inline-block; color: #fff; ${(props) => - props.a && css` + props.a && + css` display: none; `} height: 30px; diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/no-semi/no-semi.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/no-semi/no-semi.js.snap index 1f795b58ff0..0210e9278a5 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/no-semi/no-semi.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/no-semi/no-semi.js.snap @@ -105,15 +105,6 @@ aReallyLongLine012345678901234567890123456789012345678901234567890123456789 * x; ; x; -@@ -87,5 +87,6 @@ - - while (false) (function () {})(); - --aReallyLongLine012345678901234567890123456789012345678901234567890123456789 * -- (b + c); -+aReallyLongLine012345678901234567890123456789012345678901234567890123456789 * ( -+ b + c -+); ``` # Output @@ -208,9 +199,8 @@ x; while (false) (function () {})(); -aReallyLongLine012345678901234567890123456789012345678901234567890123456789 * ( - b + c -); +aReallyLongLine012345678901234567890123456789012345678901234567890123456789 * + (b + c); ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/nullish-coalescing/nullish_coalesing_operator.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/nullish-coalescing/nullish_coalesing_operator.js.snap index e2129ed3411..e199ad174ff 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/nullish-coalescing/nullish_coalesing_operator.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/nullish-coalescing/nullish_coalesing_operator.js.snap @@ -35,17 +35,15 @@ foo && (baz ?? baz); ```diff --- Prettier +++ Rome -@@ -4,8 +4,8 @@ +@@ -4,7 +4,7 @@ foo ? bar ?? foo : baz; --foo ?? bar ?? baz; -foo ?? bar ?? baz; +foo ?? (bar ?? baz); -+(foo ?? bar) ?? baz; + foo ?? bar ?? baz; // Mixing ?? and (&& or ||) requires parens - // It's a syntax error without it. ``` # Output @@ -58,7 +56,7 @@ const x = (foo, bar = foo ?? bar) => {}; foo ? bar ?? foo : baz; foo ?? (bar ?? baz); -(foo ?? bar) ?? baz; +foo ?? bar ?? baz; // Mixing ?? and (&& or ||) requires parens // It's a syntax error without it. diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/optional-chaining/chaining.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/optional-chaining/chaining.js.snap index 16230433fa0..fca4acfee44 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/optional-chaining/chaining.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/optional-chaining/chaining.js.snap @@ -96,7 +96,7 @@ new (foo?.())(); ```diff --- Prettier +++ Rome -@@ -10,20 +10,20 @@ +@@ -10,14 +10,14 @@ a?.b.c(++x).d; a?.b[3].c?.(x).d; a?.b.c; @@ -114,13 +114,6 @@ new (foo?.())(); a?.b?.c.d?.e; (a ? b : c)?.d; - - (list || list2)?.length; --(list || list2)?.[list || list2]; -+(list || list2)?.[(list || list2)]; - - async function HelloWorld() { - var x = (await foo.bar.blah)?.hi; @@ -37,18 +37,18 @@ a?.[b?.c]?.d(); @@ -146,19 +139,17 @@ new (foo?.())(); a?.[b ? c : d]; -@@ -59,28 +59,26 @@ +@@ -59,28 +59,28 @@ (function () {})?.(); (() => f)?.(); (() => f)?.x; -(a?.(x)).x; --( +a?.(x).x; -+(aaaaaaaaaaaaaaaaaaaaaaaa && + ( + aaaaaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaaaaaa && -- aaaaaaaaaaaaaaaaaaaaaaaa && -- aaaaaaaaaaaaaaaaaaaaaaaa --)?.(); -+ aaaaaaaaaaaaaaaaaaaaaaaa)?.(); + aaaaaaaaaaaaaaaaaaaaaaaa + )?.(); -let f = () => ({}?.()); -let g = () => ({}?.b); @@ -177,13 +168,13 @@ new (foo?.())(); -({ a: 1 }?.entries()); +let f = () => ({})?.(); +let g = () => ({})?.b; -+a = () => (({})?.() && a); -+a = () => (({})?.()() && a); -+a = () => (({})?.().b && a); -+a = () => (({})?.b && a); -+a = () => (({})?.b() && a); -+(a) => (({})?.()?.b && 0); -+(a) => (({})?.b?.b && 0); ++a = () => ({})?.() && a; ++a = () => ({})?.()() && a; ++a = () => ({})?.().b && a; ++a = () => ({})?.b && a; ++a = () => ({})?.b() && a; ++(a) => ({})?.()?.b && 0; ++(a) => ({})?.b?.b && 0; +(x) => ({})?.()(); +(x) => ({})?.().b; +(x) => ({})?.b(); @@ -223,7 +214,7 @@ a?.b?.c.d?.e; (a ? b : c)?.d; (list || list2)?.length; -(list || list2)?.[(list || list2)]; +(list || list2)?.[list || list2]; async function HelloWorld() { var x = (await foo.bar.blah)?.hi; @@ -260,19 +251,21 @@ a?.[b ? c : d]; (() => f)?.(); (() => f)?.x; a?.(x).x; -(aaaaaaaaaaaaaaaaaaaaaaaa && +( + aaaaaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaaaaaa && - aaaaaaaaaaaaaaaaaaaaaaaa)?.(); + aaaaaaaaaaaaaaaaaaaaaaaa +)?.(); let f = () => ({})?.(); let g = () => ({})?.b; -a = () => (({})?.() && a); -a = () => (({})?.()() && a); -a = () => (({})?.().b && a); -a = () => (({})?.b && a); -a = () => (({})?.b() && a); -(a) => (({})?.()?.b && 0); -(a) => (({})?.b?.b && 0); +a = () => ({})?.() && a; +a = () => ({})?.()() && a; +a = () => ({})?.().b && a; +a = () => ({})?.b && a; +a = () => ({})?.b() && a; +(a) => ({})?.()?.b && 0; +(a) => ({})?.b?.b && 0; (x) => ({})?.()(); (x) => ({})?.().b; (x) => ({})?.b(); diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/performance/nested-real.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/performance/nested-real.js.snap index 09b565ce6b9..271ccb8a7a1 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/performance/nested-real.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/performance/nested-real.js.snap @@ -96,15 +96,7 @@ tap.test("RecordImport.advance", (t) => { ```diff --- Prettier +++ Rome -@@ -15,70 +15,73 @@ - callback( - null, - batches.filter( -- (batch) => batch.state !== "error" && batch.state !== "completed", -+ (batch) => (batch.state !== "error" && batch.state !== "completed"), - ), - ); - }); +@@ -22,63 +22,66 @@ }; mockFS((callback) => { @@ -185,20 +177,20 @@ tap.test("RecordImport.advance", (t) => { + + t.ok(batch.getCurState().name(i18n)); }); -- -- t.ok(batch.getCurState().name(i18n)); - }); -- }); ++ }); -- t.ok(batch.getCurState().name(i18n)); +- t.ok(batch.getCurState().name(i18n)); +- }); + t.ok(batch.getCurState().name(i18n)); -+ }); + }); +- +- t.ok(batch.getCurState().name(i18n)); }); -- }); - -- t.ok(batch.getCurState().name(i18n)); ++ + t.ok(batch.getCurState().name(i18n)); -+ }); + }); +- +- t.ok(batch.getCurState().name(i18n)); }); + + t.ok(batch.getCurState().name(i18n)); @@ -233,7 +225,7 @@ tap.test("RecordImport.advance", (t) => { callback( null, batches.filter( - (batch) => (batch.state !== "error" && batch.state !== "completed"), + (batch) => batch.state !== "error" && batch.state !== "completed", ), ); }); diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/preserve-line/member-chain.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/preserve-line/member-chain.js.snap index da19c4bf882..2f0a975237c 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/preserve-line/member-chain.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/preserve-line/member-chain.js.snap @@ -72,7 +72,7 @@ const sel = this.connections ```diff --- Prettier +++ Rome -@@ -1,59 +1,39 @@ +@@ -1,59 +1,41 @@ fooBar .doSomething("Hello World") .doAnotherThing("Foo", { foo: bar }) @@ -115,19 +115,18 @@ const sel = this.connections -helloWorld - - .text() +- +- .then((t) => t); +helloWorld.text().then((t) => t); -- .then((t) => t); -- --( -- veryLongVeryLongVeryLong || -+(veryLongVeryLongVeryLong || + ( + veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || -- veryVeryVeryLongError + veryVeryVeryLongError -) -+ veryVeryVeryLongError).map( -+ (tickets) => TicketRecord.createFromSomeLongString(), -+).filter((obj) => !!obj); ++).map((tickets) => TicketRecord.createFromSomeLongString()).filter( ++ (obj) => !!obj, ++); - .map((tickets) => TicketRecord.createFromSomeLongString()) - @@ -175,11 +174,13 @@ foo.bar.baz helloWorld.text().then((t) => t); -(veryLongVeryLongVeryLong || +( + veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || - veryVeryVeryLongError).map( - (tickets) => TicketRecord.createFromSomeLongString(), -).filter((obj) => !!obj); + veryVeryVeryLongError +).map((tickets) => TicketRecord.createFromSomeLongString()).filter( + (obj) => !!obj, +); const sel = this.connections.concat( this.activities.concat(this.operators), diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/return/binaryish.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/return/binaryish.js.snap deleted file mode 100644 index c65e266f0a3..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/return/binaryish.js.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -function f() { - return ( - property.isIdentifier() && - FUNCTIONS[property.node.name] && - (object.isIdentifier(JEST_GLOBAL) || - (callee.isMemberExpression() && shouldHoistExpression(object))) && - FUNCTIONS[property.node.name](expr.get('arguments')) - ); - - return ( - chalk.bold( - 'No tests found related to files changed since last commit.\n', - ) + - chalk.dim( - patternInfo.watch ? - 'Press `a` to run all tests, or run Jest with `--watchAll`.' : - 'Run Jest without `-o` to run all tests.', - ) - ); - - return !filePath.includes(coverageDirectory) && - !filePath.endsWith(`.${SNAPSHOT_EXTENSION}`); -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -2,14 +2,18 @@ - return ( - property.isIdentifier() && - FUNCTIONS[property.node.name] && -- (object.isIdentifier(JEST_GLOBAL) || -- (callee.isMemberExpression() && shouldHoistExpression(object))) && -+ ( -+ object.isIdentifier(JEST_GLOBAL) || ( -+ callee.isMemberExpression() && shouldHoistExpression(object) -+ ) -+ ) && - FUNCTIONS[property.node.name](expr.get("arguments")) - ); - - return ( -- chalk.bold("No tests found related to files changed since last commit.\n") + -- chalk.dim( -+ chalk.bold( -+ "No tests found related to files changed since last commit.\n", -+ ) + chalk.dim( - patternInfo.watch - ? "Press `a` to run all tests, or run Jest with `--watchAll`." - : "Run Jest without `-o` to run all tests.", -@@ -17,7 +21,8 @@ - ); - - return ( -- !filePath.includes(coverageDirectory) && -- !filePath.endsWith(`.${SNAPSHOT_EXTENSION}`) -+ !filePath.includes(coverageDirectory) && !filePath.endsWith( -+ `.${SNAPSHOT_EXTENSION}`, -+ ) - ); - } -``` - -# Output - -```js -function f() { - return ( - property.isIdentifier() && - FUNCTIONS[property.node.name] && - ( - object.isIdentifier(JEST_GLOBAL) || ( - callee.isMemberExpression() && shouldHoistExpression(object) - ) - ) && - FUNCTIONS[property.node.name](expr.get("arguments")) - ); - - return ( - chalk.bold( - "No tests found related to files changed since last commit.\n", - ) + chalk.dim( - patternInfo.watch - ? "Press `a` to run all tests, or run Jest with `--watchAll`." - : "Run Jest without `-o` to run all tests.", - ) - ); - - return ( - !filePath.includes(coverageDirectory) && !filePath.endsWith( - `.${SNAPSHOT_EXTENSION}`, - ) - ); -} -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/spread/spread.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/spread/spread.js.snap deleted file mode 100644 index 36818347be0..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/spread/spread.js.snap +++ /dev/null @@ -1,41 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -const foo = { ...(a || b) }; -const foo2 = { ...a || b }; -const foo3 = { ...(a ? b : c) }; - -async () => ({ ...(await foo) }); -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,5 +1,5 @@ - const foo = { ...(a || b) }; --const foo2 = { ...(a || b) }; -+const foo2 = { ...a || b }; - const foo3 = { ...(a ? b : c) }; - - async () => ({ ...(await foo) }); -``` - -# Output - -```js -const foo = { ...(a || b) }; -const foo2 = { ...a || b }; -const foo3 = { ...(a ? b : c) }; - -async () => ({ ...(await foo) }); -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/strings/template-literals.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/strings/template-literals.js.snap deleted file mode 100644 index 396d16e8846..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/strings/template-literals.js.snap +++ /dev/null @@ -1,235 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr`); - -const x = `a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr`; - -foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() { - const x = 5; - - return x; - })() + 3 + 2 + 3 + 2 + 3 } with expr`); - -pipe.write( - `\n ${chalk.dim(`\u203A and ${more} more ${more} more ${more} more ${more}`)}`, -); - -// https://github.com/prettier/prettier/issues/1662#issue-230406820 -const content = ` -const env = ${ JSON.stringify({ - assetsRootUrl: env.assetsRootUrl, - env: env.env, - role: "client", - adsfafa: "sdfsdff", - asdfasff: "wefwefw", - fefef: "sf sdfs fdsfdsf s dfsfds" -}, null, "\t") }); -`; - -// https://github.com/prettier/prettier/issues/821#issue-210557749 -f(`${{ - a: 4, - b: 9, -}}`); - -// https://github.com/prettier/prettier/issues/1183#issue-220863505 -const makeBody = (store, assets, html) => - `${ - ReactDOMServer.renderToStaticMarkup( - - ) - }` - -// https://github.com/prettier/prettier/issues/1626#issue-229655106 -const Bar = styled.div` - color: ${props => (props.highlight.length > 0 ? palette(['text', 'dark', 'tertiary'])(props) : palette(['text', 'dark', 'primary'])(props))} !important; -` -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,6 +1,22 @@ - foo( - `a long string ${ -- 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 -+ 1 + -+ 2 + -+ 3 + -+ 2 + -+ 3 + -+ 2 + -+ 3 + -+ 2 + -+ 3 + -+ 2 + -+ 3 + -+ 2 + -+ 3 + -+ 2 + -+ 3 + -+ 2 + -+ 3 - } with expr`, - ); - -``` - -# Output - -```js -foo( - `a long string ${ - 1 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 - } with expr`, -); - -const x = `a long string ${ - 1 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - (function () { - return 3; - })() + - 3 + - 2 + - 3 + - 2 + - 3 -} with expr`; - -foo( - `a long string ${ - 1 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - 3 + - 2 + - (function () { - const x = 5; - - return x; - })() + - 3 + - 2 + - 3 + - 2 + - 3 - } with expr`, -); - -pipe.write( - `\n ${chalk.dim( - `\u203A and ${more} more ${more} more ${more} more ${more}`, - )}`, -); - -// https://github.com/prettier/prettier/issues/1662#issue-230406820 -const content = ` -const env = ${JSON.stringify( - { - assetsRootUrl: env.assetsRootUrl, - env: env.env, - role: "client", - adsfafa: "sdfsdff", - asdfasff: "wefwefw", - fefef: "sf sdfs fdsfdsf s dfsfds", - }, - null, - "\t", -)}); -`; - -// https://github.com/prettier/prettier/issues/821#issue-210557749 -f( - `${{ - a: 4, - b: 9, - }}`, -); - -// https://github.com/prettier/prettier/issues/1183#issue-220863505 -const makeBody = (store, assets, html) => - `${ReactDOMServer.renderToStaticMarkup( - , - )}`; - -// https://github.com/prettier/prettier/issues/1626#issue-229655106 -const Bar = styled.div` - color: ${(props) => - props.highlight.length > 0 - ? palette(["text", "dark", "tertiary"])(props) - : palette(["text", "dark", "primary"])(props)} !important; -`; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/switch/switch.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/switch/switch.js.snap deleted file mode 100644 index 685875b81b3..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/switch/switch.js.snap +++ /dev/null @@ -1,133 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -switch (a) { - case 3: - alert( '3' ); - break; - case 4: - alert( '4' ); - break; - case 5: - alert( '5' ); - break; - default: - alert( 'default' ); -} - -switch (veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong) { - case 3: - alert( '3' ); - break; - default: - alert( 'default' ); -} - -switch (veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong > veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong) { - case 3: - alert( '3' ); - break; - default: - alert( 'default' ); -} - -switch ($veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVariableName) { -} - -switch ($longButSlightlyShorterVariableName && $anotherSlightlyShorterVariableName) { -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -23,8 +23,7 @@ - } - - switch ( -- veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong > -- veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong -+ veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong > veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong - ) { - case 3: - alert("3"); -@@ -34,13 +33,11 @@ - } - - switch ( -- $veryLongAndVeryVerboseVariableName && -- $anotherVeryLongAndVeryVerboseVariableName -+ $veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVariableName - ) { - } - - switch ( -- $longButSlightlyShorterVariableName && -- $anotherSlightlyShorterVariableName -+ $longButSlightlyShorterVariableName && $anotherSlightlyShorterVariableName - ) { - } -``` - -# Output - -```js -switch (a) { - case 3: - alert("3"); - break; - case 4: - alert("4"); - break; - case 5: - alert("5"); - break; - default: - alert("default"); -} - -switch ( - veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong -) { - case 3: - alert("3"); - break; - default: - alert("default"); -} - -switch ( - veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong > veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong -) { - case 3: - alert("3"); - break; - default: - alert("default"); -} - -switch ( - $veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVariableName -) { -} - -switch ( - $longButSlightlyShorterVariableName && $anotherSlightlyShorterVariableName -) { -} -``` - - -# Lines exceeding max width of 80 characters -``` - 26: veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong > veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong - 36: $veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVariableName -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/template-literals/sequence-expressions.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/template-literals/sequence-expressions.js.snap deleted file mode 100644 index 2399e8cce65..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/template-literals/sequence-expressions.js.snap +++ /dev/null @@ -1,36 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs -assertion_line: 271 -info: - test_file: js/template-literals/sequence-expressions.js ---- - -# Input - -```js -`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${(1, 2)}`; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,3 +1,2 @@ --`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${ -- (1, 2) --}`; -+`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${(1, -+2)}`; -``` - -# Output - -```js -`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${(1, -2)}`; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/binary.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/binary.js.snap index 0ed2b5c73fd..74481420525 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/binary.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/binary.js.snap @@ -25,16 +25,14 @@ room = room.map((row, rowIndex) => ( ```diff --- Prettier +++ Rome -@@ -1,17 +1,21 @@ +@@ -1,17 +1,19 @@ const funnelSnapshotCard = -- (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || -- (report === COMPANY_OVERVIEW && + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && - !ReportGK.xar_metrics_active_capitol_v2_company_metrics) ? ( - - ) : null; -+ (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || ( -+ report === COMPANY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2_company_metrics -+ ) ++ !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; @@ -51,12 +49,10 @@ room = room.map((row, rowIndex) => ( + (row, rowIndex) => + row.map( + (col, colIndex) => -+ ( -+ rowIndex === 0 || -+ colIndex === 0 || -+ rowIndex === height || -+ colIndex === width -+ ) ++ rowIndex === 0 || ++ colIndex === 0 || ++ rowIndex === height || ++ colIndex === width + ? 1 + : 0, + ), @@ -67,9 +63,9 @@ room = room.map((row, rowIndex) => ( ```js const funnelSnapshotCard = - (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || ( - report === COMPANY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2_company_metrics - ) + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) ? : null; @@ -77,12 +73,10 @@ room = room.map( (row, rowIndex) => row.map( (col, colIndex) => - ( - rowIndex === 0 || - colIndex === 0 || - rowIndex === height || - colIndex === width - ) + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width ? 1 : 0, ), @@ -90,8 +84,4 @@ room = room.map( ``` -# Lines exceeding max width of 80 characters -``` - 3: report === COMPANY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2_company_metrics -``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/func-call.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/func-call.js.snap index 51584361789..649e7f15f15 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/func-call.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/func-call.js.snap @@ -21,13 +21,12 @@ fn( ```diff --- Prettier +++ Rome -@@ -1,8 +1,7 @@ - fn( +@@ -2,7 +2,7 @@ bifornCringerMoshedPerplexSawder, askTrovenaBeenaDependsRowans, -- glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && - anodyneCondosMalateOverateRetinol -+ glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && anodyneCondosMalateOverateRetinol ++ anodyneCondosMalateOverateRetinol ? annularCooeedSplicesWalksWayWay : kochabCooieGameOnOboleUnweave, ); @@ -39,15 +38,12 @@ fn( fn( bifornCringerMoshedPerplexSawder, askTrovenaBeenaDependsRowans, - glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && anodyneCondosMalateOverateRetinol + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol ? annularCooeedSplicesWalksWayWay : kochabCooieGameOnOboleUnweave, ); ``` -# Lines exceeding max width of 80 characters -``` - 4: glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && anodyneCondosMalateOverateRetinol -``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/indent-after-paren.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/indent-after-paren.js.snap index 872c94889df..5117448408d 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/indent-after-paren.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/indent-after-paren.js.snap @@ -305,60 +305,8 @@ fn?.[ ```diff --- Prettier +++ Rome -@@ -210,54 +210,44 @@ - )(Fooooooooooo.Fooooooooooo); - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- (glimseGlyphsHazardNoopsTieTie === 0 -+ askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- (glimseGlyphsHazardNoopsTieTie === 0 && -- kochabCooieGameOnOboleUnweave === Math.PI -+ askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- (glimseGlyphsHazardNoopsTieTie === 0 -+ askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol - ).Fooooooooooo.Fooooooooooo; - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- (glimseGlyphsHazardNoopsTieTie === 0 && -- kochabCooieGameOnOboleUnweave === Math.PI -+ askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol - ).Fooooooooooo.Fooooooooooo; - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- (glimseGlyphsHazardNoopsTieTie === 0 -+ askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- (glimseGlyphsHazardNoopsTieTie === 0 && -- kochabCooieGameOnOboleUnweave === Math.PI -+ askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); - - bifornCringerMoshedPerplexSawder = ( -- glimseGlyphsHazardNoopsTieTie === 0 && -- kochabCooieGameOnOboleUnweave === Math.PI -+ glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI +@@ -255,9 +255,9 @@ + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol -).annularCooeedSplicesWalksWayWay @@ -370,18 +318,6 @@ fn?.[ foo = ( coooooooooooooooooooooooooooooooooooooooooooooooooooond -@@ -280,8 +270,9 @@ - - const decorated = (arg, ignoreRequestError) => { - return ( -- typeof arg === "string" || -- (arg && arg.valueOf && typeof arg.valueOf() === "string") -+ typeof arg === "string" || ( -+ arg && arg.valueOf && typeof arg.valueOf() === "string" -+ ) - ? $delegate(arg, ignoreRequestError) - : handleAsyncOperations(arg, ignoreRequestError) - ).foo(); ``` # Output @@ -599,39 +535,49 @@ foo36 = new ( )(Fooooooooooo.Fooooooooooo); bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol ).Fooooooooooo.Fooooooooooo; bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol ).Fooooooooooo.Fooooooooooo; bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); bifornCringerMoshedPerplexSawder = ( - glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol ).annularCooeedSplicesWalksWayWay.annularCooeedSplicesWalksWayWay( @@ -659,9 +605,8 @@ foo = const decorated = (arg, ignoreRequestError) => { return ( - typeof arg === "string" || ( - arg && arg.valueOf && typeof arg.valueOf() === "string" - ) + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") ? $delegate(arg, ignoreRequestError) : handleAsyncOperations(arg, ignoreRequestError) ).foo(); @@ -727,11 +672,4 @@ fn?.[ ``` -# Lines exceeding max width of 80 characters -``` - 218: askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - 229: askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - 240: askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - 245: glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI -``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/nested.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/nested.js.snap index b8e0f390d03..edeea9998f0 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/nested.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/ternaries/nested.js.snap @@ -149,7 +149,7 @@ a const message = i % 3 === 0 && i % 5 === 0 -@@ -60,13 +58,13 @@ +@@ -60,7 +58,8 @@ ? 3 //'There was an issue with your CVC number' : true //state == 'invalid_expiry' ? 4 //'Expiry must be sometime in the past.' @@ -159,13 +159,6 @@ a const foo = (
= | { kind: "not-test-editor1" } | { kind: "not-test-editor2" }; - -// Note: there are trailing whitespace in this file -` - - -` + ` - - -`; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -6,8 +6,7 @@ - ` - - --` + -- ` -+` + ` - - - `; -``` - -# Output - -```js -export type Result = - | { kind: "not-test-editor1" } - | { kind: "not-test-editor2" }; - -// Note: there are trailing whitespace in this file -` - - -` + ` - - -`; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/unary-expression/comments.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/unary-expression/comments.js.snap index 87d1fc70318..81531f7dacb 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/unary-expression/comments.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/unary-expression/comments.js.snap @@ -298,7 +298,7 @@ async function bar2() { ```diff --- Prettier +++ Rome -@@ -1,283 +1,218 @@ +@@ -1,283 +1,210 @@ !x; -!(x /* foo */); -!(/* foo */ x); @@ -326,42 +326,50 @@ async function bar2() { !(x + y); -!((x + y) /* foo */); -!(/* foo */ (x + y)); -+!(x + y /* foo */); -+!(/* foo */ x + y); - !( - /* foo */ +-!( +- /* foo */ - (x + y) -+ x + y - ); - !( +-); +-!( - (x + y) -+ x + y - /* foo */ - ); - !( +- /* foo */ +-); +-!( - (x + y) // foo -+ x + y // foo - ); +-); ++!(x + y) /* foo */; ++! /* foo */ (x + y); ++! ++/* foo */ ++(x + y); ++!(x + y) ++/* foo */ ++; ++!(x + y); // foo !(x || y); -!(/* foo */ (x || y)); -!((x || y) /* foo */); -+!(/* foo */ x || y); -+!(x || y /* foo */); - !( - /* foo */ +-!( +- /* foo */ - (x || y) -+ x || y - ); - !( +-); +-!( - (x || y) -+ x || y - /* foo */ - ); - !( +- /* foo */ +-); +-!( - (x || y) // foo -+ x || y // foo - ); +-); ++! /* foo */ (x || y); ++!(x || y) /* foo */; ++! ++/* foo */ ++(x || y); ++!(x || y) ++/* foo */ ++; ++!(x || y); // foo ![1, 2, 3]; -!([1, 2, 3] /* foo */); @@ -763,34 +771,26 @@ x; !x; // foo !(x + y); -!(x + y /* foo */); -!(/* foo */ x + y); -!( - /* foo */ - x + y -); -!( - x + y - /* foo */ -); -!( - x + y // foo -); +!(x + y) /* foo */; +! /* foo */ (x + y); +! +/* foo */ +(x + y); +!(x + y) +/* foo */ +; +!(x + y); // foo !(x || y); -!(/* foo */ x || y); -!(x || y /* foo */); -!( - /* foo */ - x || y -); -!( - x || y - /* foo */ -); -!( - x || y // foo -); +! /* foo */ (x || y); +!(x || y) /* foo */; +! +/* foo */ +(x || y); +!(x || y) +/* foo */ +; +!(x || y); // foo ![1, 2, 3]; ![1, 2, 3] /* foo */; diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/as/assignment2.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/as/assignment2.ts.snap index 7bb71063c36..5b3bb63e957 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/as/assignment2.ts.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/as/assignment2.ts.snap @@ -41,20 +41,7 @@ const originalPrototype = originalConstructor.prototype as TComponent & Injectio ```diff --- Prettier +++ Rome -@@ -21,14 +21,17 @@ - this.initialValues = - undefined; - --const extraRendererAttrs = ((attrs.rendererAttrs && -- this.utils.safeParseJsonString(attrs.rendererAttrs)) || -- Object.create(null)) as FieldService.RendererAttributes; -+const extraRendererAttrs = ( -+ ( -+ attrs.rendererAttrs && this.utils.safeParseJsonString(attrs.rendererAttrs) -+ ) || Object.create(null) -+) as FieldService.RendererAttributes; - - const annotate = (angular.injector as any).$$annotate as ( +@@ -29,6 +29,7 @@ fn: Function, ) => string[]; @@ -92,11 +79,9 @@ angular.module("foo").directive("formIsolator", () => { this.initialValues = undefined; -const extraRendererAttrs = ( - ( - attrs.rendererAttrs && this.utils.safeParseJsonString(attrs.rendererAttrs) - ) || Object.create(null) -) as FieldService.RendererAttributes; +const extraRendererAttrs = ((attrs.rendererAttrs && + this.utils.safeParseJsonString(attrs.rendererAttrs)) || + Object.create(null)) as FieldService.RendererAttributes; const annotate = (angular.injector as any).$$annotate as ( fn: Function, diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/as/ternary.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/as/ternary.ts.snap deleted file mode 100644 index 190657cd459..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/as/ternary.ts.snap +++ /dev/null @@ -1,132 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz) as Fooooooooooo; - -foo = (condition ? firstValue : secondValue) as SomeType; - -const foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz) as Fooooooooooo; - -function foo() { - return (coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz) as Fooooooooooo; -} - -function foo() { - throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz) as Fooooooooooo; -} - -function foo() { - void ((coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz) as Fooooooooooo); -} - -bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + - ((glimseGlyphsHazardNoopsTieTie === 0 - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol) as AnnularCooeedSplicesWalksWayWay); - -bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + - ((glimseGlyphsHazardNoopsTieTie === 0 && - kochabCooieGameOnOboleUnweave === Math.PI - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol) as AnnularCooeedSplicesWalksWayWay); -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -37,14 +37,11 @@ - } - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- ((glimseGlyphsHazardNoopsTieTie === 0 -+ askTrovenaBeenaDependsRowans + ((glimseGlyphsHazardNoopsTieTie === 0 - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol) as AnnularCooeedSplicesWalksWayWay); - - bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- ((glimseGlyphsHazardNoopsTieTie === 0 && -- kochabCooieGameOnOboleUnweave === Math.PI -+ askTrovenaBeenaDependsRowans + ((glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol) as AnnularCooeedSplicesWalksWayWay); -``` - -# Output - -```js -foo = ( - coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz -) as Fooooooooooo; - -foo = (condition ? firstValue : secondValue) as SomeType; - -const foo = ( - coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz -) as Fooooooooooo; - -function foo() { - return ( - coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz - ) as Fooooooooooo; -} - -function foo() { - throw ( - coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz - ) as Fooooooooooo; -} - -function foo() { - void (( - coooooooooooooooooooooooooooooooooooooooooooooooooooond - ? baaaaaaaaaaaaaaaaaaaaar - : baaaaaaaaaaaaaaaaaaaaaz - ) as Fooooooooooo); -} - -bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + ((glimseGlyphsHazardNoopsTieTie === 0 - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol) as AnnularCooeedSplicesWalksWayWay); - -bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + ((glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol) as AnnularCooeedSplicesWalksWayWay); -``` - - -# Lines exceeding max width of 80 characters -``` - 45: askTrovenaBeenaDependsRowans + ((glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementationErrors.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementationErrors.ts.snap deleted file mode 100644 index 9f272efe802..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementationErrors.ts.snap +++ /dev/null @@ -1,201 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -// @allowUnreachableCode: true - -// FunctionExpression with no return type annotation with multiple return statements with unrelated types -var f1 = function () { - return ''; - return 3; -}; -var f2 = function x() { - return ''; - return 3; -}; -var f3 = () => { - return ''; - return 3; -}; - -// FunctionExpression with no return type annotation with return branch of number[] and other of string[] -var f4 = function () { - if (true) { - return ['']; - } else { - return [1]; - } -} - -// Function implementation with non -void return type annotation with no return -function f5(): number { -} - -var m; -// Function signature with parameter initializer referencing in scope local variable -function f6(n = m) { - var m = 4; -} - -// Function signature with initializer referencing other parameter to the right -function f7(n = m, m?) { -} - -// FunctionExpression with non -void return type annotation with a throw, no return, and other code -// Should be error but isn't -undefined === function (): number { - throw undefined; - var x = 4; -}; - -class Base { private x; } -class AnotherClass { private y; } -class Derived1 extends Base { private m; } -class Derived2 extends Base { private n; } -function f8() { - return new Derived1(); - return new Derived2(); -} -var f9 = function () { - return new Derived1(); - return new Derived2(); -}; -var f10 = () => { - return new Derived1(); - return new Derived2(); -}; -function f11() { - return new Base(); - return new AnotherClass(); -} -var f12 = function () { - return new Base(); - return new AnotherClass(); -}; -var f13 = () => { - return new Base(); - return new AnotherClass(); -}; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -37,11 +37,10 @@ - - // FunctionExpression with non -void return type annotation with a throw, no return, and other code - // Should be error but isn't --undefined === -- function (): number { -- throw undefined; -- var x = 4; -- }; -+undefined === function (): number { -+ throw undefined; -+ var x = 4; -+}; - - class Base { - private x; -``` - -# Output - -```js -// @allowUnreachableCode: true - -// FunctionExpression with no return type annotation with multiple return statements with unrelated types -var f1 = function () { - return ""; - return 3; -}; -var f2 = function x() { - return ""; - return 3; -}; -var f3 = () => { - return ""; - return 3; -}; - -// FunctionExpression with no return type annotation with return branch of number[] and other of string[] -var f4 = function () { - if (true) { - return [""]; - } else { - return [1]; - } -}; - -// Function implementation with non -void return type annotation with no return -function f5(): number {} - -var m; -// Function signature with parameter initializer referencing in scope local variable -function f6(n = m) { - var m = 4; -} - -// Function signature with initializer referencing other parameter to the right -function f7(n = m, m?) {} - -// FunctionExpression with non -void return type annotation with a throw, no return, and other code -// Should be error but isn't -undefined === function (): number { - throw undefined; - var x = 4; -}; - -class Base { - private x; -} -class AnotherClass { - private y; -} -class Derived1 extends Base { - private m; -} -class Derived2 extends Base { - private n; -} -function f8() { - return new Derived1(); - return new Derived2(); -} -var f9 = function () { - return new Derived1(); - return new Derived2(); -}; -var f10 = () => { - return new Derived1(); - return new Derived2(); -}; -function f11() { - return new Base(); - return new AnotherClass(); -} -var f12 = function () { - return new Base(); - return new AnotherClass(); -}; -var f13 = () => { - return new Base(); - return new AnotherClass(); -}; -``` - - -# Lines exceeding max width of 80 characters -``` - 3: // FunctionExpression with no return type annotation with multiple return statements with unrelated types - 17: // FunctionExpression with no return type annotation with return branch of number[] and other of string[] - 30: // Function signature with parameter initializer referencing in scope local variable - 38: // FunctionExpression with non -void return type annotation with a throw, no return, and other code -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementations.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementations.ts.snap deleted file mode 100644 index eb26c047293..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/conformance/types/functions/functionImplementations.ts.snap +++ /dev/null @@ -1,393 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -// @allowUnreachableCode: true - -// FunctionExpression with no return type annotation and no return statement returns void -var v: void = function () { } (); - -// FunctionExpression f with no return type annotation and directly references f in its body returns any -var a: any = function f() { - return f; -}; -var a: any = function f() { - return f(); -}; - -// FunctionExpression f with no return type annotation and indirectly references f in its body returns any -var a: any = function f() { - var x = f; - return x; -}; - -// Two mutually recursive function implementations with no return type annotations -function rec1() { - return rec2(); -} -function rec2() { - return rec1(); -} -var a = rec1(); -var a = rec2(); - -// Two mutually recursive function implementations with return type annotation in one -function rec3(): number { - return rec4(); -} -function rec4() { - return rec3(); -} -var n: number; -var n = rec3(); -var n = rec4(); - -// FunctionExpression with no return type annotation and returns a number -var n = function () { - return 3; -} (); - -// FunctionExpression with no return type annotation and returns null -var nu = null; -var nu = function () { - return null; -} (); - -// FunctionExpression with no return type annotation and returns undefined -var un = undefined; -var un = function () { - return undefined; -} (); - -// FunctionExpression with no return type annotation and returns a type parameter type -var n = function (x: T) { - return x; -} (4); - -// FunctionExpression with no return type annotation and returns a constrained type parameter type -var n = function (x: T) { - return x; -} (4); - -// FunctionExpression with no return type annotation with multiple return statements with identical types -var n = function () { - return 3; - return 5; -}(); - -// Otherwise, the inferred return type is the first of the types of the return statement expressions -// in the function body that is a supertype of each of the others, -// ignoring return statements with no expressions. -// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. -// FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns -class Base { private m; } -class Derived extends Base { private q; } -var b: Base; -var b = function () { - return new Base(); return new Derived(); -} (); - -// FunctionExpression with no return type annotation with multiple return statements with one a recursive call -var a = function f() { - return new Base(); return new Derived(); return f(); // ? -} (); - -// FunctionExpression with non -void return type annotation with a single throw statement -undefined === function (): number { - throw undefined; -}; - -// Type of 'this' in function implementation is 'any' -function thisFunc() { - var x = this; - var x: any; -} - -// Function signature with optional parameter, no type annotation and initializer has initializer's type -function opt1(n = 4) { - var m = n; - var m: number; -} - -// Function signature with optional parameter, no type annotation and initializer has initializer's widened type -function opt2(n = { x: null, y: undefined }) { - var m = n; - var m: { x: any; y: any }; -} - -// Function signature with initializer referencing other parameter to the left -function opt3(n: number, m = n) { - var y = m; - var y: number; -} - -// Function signature with optional parameter has correct codegen -// (tested above) - -// FunctionExpression with non -void return type annotation return with no expression -function f6(): number { - return; -} - -class Derived2 extends Base { private r: string; } -class AnotherClass { private x } -// if f is a contextually typed function expression, the inferred return type is the union type -// of the types of the return statement expressions in the function body, -// ignoring return statements with no expressions. -var f7: (x: number) => string | number = x => { // should be (x: number) => number | string - if (x < 0) { return x; } - return x.toString(); -} -var f8: (x: number) => any = x => { // should be (x: number) => Base - return new Base(); - return new Derived2(); -} -var f9: (x: number) => any = x => { // should be (x: number) => Base - return new Base(); - return new Derived(); - return new Derived2(); -} -var f10: (x: number) => any = x => { // should be (x: number) => Derived | Derived1 - return new Derived(); - return new Derived2(); -} -var f11: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass - return new Base(); - return new AnotherClass(); -} -var f12: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass - return new Base(); - return; // should be ignored - return new AnotherClass(); -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -96,10 +96,9 @@ - })(); - - // FunctionExpression with non -void return type annotation with a single throw statement --undefined === -- function (): number { -- throw undefined; -- }; -+undefined === function (): number { -+ throw undefined; -+}; - - // Type of 'this' in function implementation is 'any' - function thisFunc() { -``` - -# Output - -```js -// @allowUnreachableCode: true - -// FunctionExpression with no return type annotation and no return statement returns void -var v: void = (function () {})(); - -// FunctionExpression f with no return type annotation and directly references f in its body returns any -var a: any = function f() { - return f; -}; -var a: any = function f() { - return f(); -}; - -// FunctionExpression f with no return type annotation and indirectly references f in its body returns any -var a: any = function f() { - var x = f; - return x; -}; - -// Two mutually recursive function implementations with no return type annotations -function rec1() { - return rec2(); -} -function rec2() { - return rec1(); -} -var a = rec1(); -var a = rec2(); - -// Two mutually recursive function implementations with return type annotation in one -function rec3(): number { - return rec4(); -} -function rec4() { - return rec3(); -} -var n: number; -var n = rec3(); -var n = rec4(); - -// FunctionExpression with no return type annotation and returns a number -var n = (function () { - return 3; -})(); - -// FunctionExpression with no return type annotation and returns null -var nu = null; -var nu = (function () { - return null; -})(); - -// FunctionExpression with no return type annotation and returns undefined -var un = undefined; -var un = (function () { - return undefined; -})(); - -// FunctionExpression with no return type annotation and returns a type parameter type -var n = (function (x: T) { - return x; -})(4); - -// FunctionExpression with no return type annotation and returns a constrained type parameter type -var n = (function (x: T) { - return x; -})(4); - -// FunctionExpression with no return type annotation with multiple return statements with identical types -var n = (function () { - return 3; - return 5; -})(); - -// Otherwise, the inferred return type is the first of the types of the return statement expressions -// in the function body that is a supertype of each of the others, -// ignoring return statements with no expressions. -// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. -// FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns -class Base { - private m; -} -class Derived extends Base { - private q; -} -var b: Base; -var b = (function () { - return new Base(); - return new Derived(); -})(); - -// FunctionExpression with no return type annotation with multiple return statements with one a recursive call -var a = (function f() { - return new Base(); - return new Derived(); - return f(); // ? -})(); - -// FunctionExpression with non -void return type annotation with a single throw statement -undefined === function (): number { - throw undefined; -}; - -// Type of 'this' in function implementation is 'any' -function thisFunc() { - var x = this; - var x: any; -} - -// Function signature with optional parameter, no type annotation and initializer has initializer's type -function opt1(n = 4) { - var m = n; - var m: number; -} - -// Function signature with optional parameter, no type annotation and initializer has initializer's widened type -function opt2(n = { x: null, y: undefined }) { - var m = n; - var m: { x: any; y: any }; -} - -// Function signature with initializer referencing other parameter to the left -function opt3(n: number, m = n) { - var y = m; - var y: number; -} - -// Function signature with optional parameter has correct codegen -// (tested above) - -// FunctionExpression with non -void return type annotation return with no expression -function f6(): number { - return; -} - -class Derived2 extends Base { - private r: string; -} -class AnotherClass { - private x; -} -// if f is a contextually typed function expression, the inferred return type is the union type -// of the types of the return statement expressions in the function body, -// ignoring return statements with no expressions. -var f7: (x: number) => string | number = (x) => { - // should be (x: number) => number | string - if (x < 0) { - return x; - } - return x.toString(); -}; -var f8: (x: number) => any = (x) => { - // should be (x: number) => Base - return new Base(); - return new Derived2(); -}; -var f9: (x: number) => any = (x) => { - // should be (x: number) => Base - return new Base(); - return new Derived(); - return new Derived2(); -}; -var f10: (x: number) => any = (x) => { - // should be (x: number) => Derived | Derived1 - return new Derived(); - return new Derived2(); -}; -var f11: (x: number) => any = (x) => { - // should be (x: number) => Base | AnotherClass - return new Base(); - return new AnotherClass(); -}; -var f12: (x: number) => any = (x) => { - // should be (x: number) => Base | AnotherClass - return new Base(); - return; // should be ignored - return new AnotherClass(); -}; -``` - - -# Lines exceeding max width of 80 characters -``` - 3: // FunctionExpression with no return type annotation and no return statement returns void - 6: // FunctionExpression f with no return type annotation and directly references f in its body returns any - 14: // FunctionExpression f with no return type annotation and indirectly references f in its body returns any - 20: // Two mutually recursive function implementations with no return type annotations - 30: // Two mutually recursive function implementations with return type annotation in one - 58: // FunctionExpression with no return type annotation and returns a type parameter type - 63: // FunctionExpression with no return type annotation and returns a constrained type parameter type - 68: // FunctionExpression with no return type annotation with multiple return statements with identical types - 74: // Otherwise, the inferred return type is the first of the types of the return statement expressions - 77: // A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. - 78: // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns - 91: // FunctionExpression with no return type annotation with multiple return statements with one a recursive call - 98: // FunctionExpression with non -void return type annotation with a single throw statement - 109: // Function signature with optional parameter, no type annotation and initializer has initializer's type - 115: // Function signature with optional parameter, no type annotation and initializer has initializer's widened type - 130: // FunctionExpression with non -void return type annotation return with no expression - 141: // if f is a contextually typed function expression, the inferred return type is the union type -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/template-literals/as-expression.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/template-literals/as-expression.ts.snap deleted file mode 100644 index a63a89b21a1..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/template-literals/as-expression.ts.snap +++ /dev/null @@ -1,58 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -const a = `${(foo + bar) as baz}`; -const b = `${(veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + bar) as baz}`; -const b = `${(foo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar) as baz}`; -const b = `${(foo + bar) as veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBaz}`; -const b = `${(veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar) as veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBaz}`; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -9,6 +9,7 @@ - (foo + bar) as veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBaz - }`; - const b = `${ -- (veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + -- veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar) as veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBaz -+ ( -+ veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar -+ ) as veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBaz - }`; -``` - -# Output - -```js -const a = `${(foo + bar) as baz}`; -const b = `${ - (veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + bar) as baz -}`; -const b = `${ - (foo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar) as baz -}`; -const b = `${ - (foo + bar) as veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBaz -}`; -const b = `${ - ( - veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar - ) as veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBaz -}`; -``` - - -# Lines exceeding max width of 80 characters -``` - 13: veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongFoo + veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongBar -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/ternaries/indent.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/ternaries/indent.ts.snap index 8e87307b8da..a448b013054 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/ternaries/indent.ts.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/ternaries/indent.ts.snap @@ -63,13 +63,8 @@ foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond ```diff --- Prettier +++ Rome -@@ -11,13 +11,12 @@ - ).TSESTree!.BinaryExpression; - - bifornCringerMoshedPerplexSawder = ( -- glimseGlyphsHazardNoopsTieTie === 0 && -- kochabCooieGameOnOboleUnweave === Math.PI -+ glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI +@@ -15,9 +15,9 @@ + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol -).annularCooeedSplicesWalksWayWay @@ -81,13 +76,8 @@ foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond foo = ( callNode.parent?.type === AST_NODE_TYPES.ChainExpression -@@ -32,17 +31,15 @@ - ).TSESTree!.BinaryExpression!; - - bifornCringerMoshedPerplexSawder = ( -- glimseGlyphsHazardNoopsTieTie === 0 && -- kochabCooieGameOnOboleUnweave === Math.PI -+ glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI +@@ -36,9 +36,9 @@ + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol -).annularCooeedSplicesWalksWayWay @@ -98,12 +88,7 @@ foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond +)!.annularCooeedSplicesWalksWayWay()!; bifornCringerMoshedPerplexSawder = -- askTrovenaBeenaDependsRowans + -- (glimseGlyphsHazardNoopsTieTie === 0 -+ askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 - ? averredBathersBoxroomBuggyNurl - : anodyneCondosMalateOverateRetinol - ).Foo!.foo; + askTrovenaBeenaDependsRowans + ``` # Output @@ -122,7 +107,8 @@ foo = ( ).TSESTree!.BinaryExpression; bifornCringerMoshedPerplexSawder = ( - glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol ).annularCooeedSplicesWalksWayWay.annularCooeedSplicesWalksWayWay( @@ -142,7 +128,8 @@ foo = ( ).TSESTree!.BinaryExpression!; bifornCringerMoshedPerplexSawder = ( - glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol ).annularCooeedSplicesWalksWayWay.annularCooeedSplicesWalksWayWay( @@ -150,7 +137,8 @@ bifornCringerMoshedPerplexSawder = ( )!.annularCooeedSplicesWalksWayWay()!; bifornCringerMoshedPerplexSawder = - askTrovenaBeenaDependsRowans + (glimseGlyphsHazardNoopsTieTie === 0 + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? averredBathersBoxroomBuggyNurl : anodyneCondosMalateOverateRetinol ).Foo!.foo; @@ -169,9 +157,4 @@ foo = ( ``` -# Lines exceeding max width of 80 characters -``` - 14: glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI - 34: glimseGlyphsHazardNoopsTieTie === 0 && kochabCooieGameOnOboleUnweave === Math.PI -``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap index fade54f1ad8..bdc00425873 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap @@ -1,8 +1,5 @@ --- source: crates/rome_js_formatter/tests/prettier_tests.rs -assertion_line: 271 -info: - test_file: typescript/webhost/webtsc.ts --- # Input @@ -120,18 +117,14 @@ namespace TypeScript.WebTsc { ```diff --- Prettier +++ Rome -@@ -40,9 +40,11 @@ - fileStream.Position = 0; +@@ -41,8 +41,8 @@ // [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8 fileStream.Charset = -- bom.length >= 2 && + bom.length >= 2 && - ((bom.charCodeAt(0) === 0xff && bom.charCodeAt(1) === 0xfe) || - (bom.charCodeAt(0) === 0xfe && bom.charCodeAt(1) === 0xff)) -+ bom.length >= 2 && ( -+ (bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE) || ( -+ bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF -+ ) -+ ) ++ ((bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE) || ++ (bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF)) ? "unicode" : "utf-8"; } @@ -182,11 +175,9 @@ namespace TypeScript.WebTsc { fileStream.Position = 0; // [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8 fileStream.Charset = - bom.length >= 2 && ( - (bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE) || ( - bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF - ) - ) + bom.length >= 2 && + ((bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE) || + (bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF)) ? "unicode" : "utf-8"; } From d5de48c170e5dde5dabfb38b46a2596b8d97aad4 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 17 Aug 2022 18:29:56 +0200 Subject: [PATCH 2/3] Format editor, website and npm files --- npm/rome/scripts/postinstall.js | 3 ++- npm/rome/scripts/update-nightly-version.mjs | 3 ++- website/playground/src/romeWorker.ts | 2 +- website/playground/src/utils.ts | 20 ++++++++------------ website/src/_data/env.js | 4 ++-- website/src/_includes/scripts/funding.js | 3 ++- website/src/_includes/scripts/index.js | 5 +++-- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/npm/rome/scripts/postinstall.js b/npm/rome/scripts/postinstall.js index 3053f30981e..392c13c4b65 100644 --- a/npm/rome/scripts/postinstall.js +++ b/npm/rome/scripts/postinstall.js @@ -31,7 +31,8 @@ if (binName) { require("fs").chmodSync(binPath, 0o755); } catch { console.warn( - "The Rome CLI postinstall script failed to set execution permissions to the native binary. " + "Running Rome from the npm package will probably not work correctly.", + "The Rome CLI postinstall script failed to set execution permissions to the native binary. " + + "Running Rome from the npm package will probably not work correctly.", ); } } diff --git a/npm/rome/scripts/update-nightly-version.mjs b/npm/rome/scripts/update-nightly-version.mjs index 0508d9b13ee..1b2fbeabb40 100644 --- a/npm/rome/scripts/update-nightly-version.mjs +++ b/npm/rome/scripts/update-nightly-version.mjs @@ -15,7 +15,8 @@ if (!version.includes("-")) { } if ( - typeof process.env.GITHUB_SHA !== "string" || process.env.GITHUB_SHA === "" + typeof process.env.GITHUB_SHA !== "string" || + process.env.GITHUB_SHA === "" ) { throw new Error("GITHUB_SHA environment variable is undefined"); } diff --git a/website/playground/src/romeWorker.ts b/website/playground/src/romeWorker.ts index 0f0663c0022..e364eba923d 100644 --- a/website/playground/src/romeWorker.ts +++ b/website/playground/src/romeWorker.ts @@ -35,7 +35,7 @@ function getPathForType( return PATH_SCRIPT; } - return PATHS_MODULE[(Number(isTypeScript) * 2) + Number(isJsx)]; + return PATHS_MODULE[Number(isTypeScript) * 2 + Number(isJsx)]; } type CurrentFile = { diff --git a/website/playground/src/utils.ts b/website/playground/src/utils.ts index 932dbf16c32..aece850e9cc 100644 --- a/website/playground/src/utils.ts +++ b/website/playground/src/utils.ts @@ -58,25 +58,21 @@ export function usePlaygroundState( searchParams.get("lineWidth") ?? defaultRomeConfig.lineWidth, ), indentStyle: - (searchParams.get( - "indentStyle", - ) as IndentStyle) ?? defaultRomeConfig.indentStyle, + (searchParams.get("indentStyle") as IndentStyle) ?? + defaultRomeConfig.indentStyle, quoteStyle: - (searchParams.get( - "quoteStyle", - ) as QuoteStyle) ?? defaultRomeConfig.quoteStyle, + (searchParams.get("quoteStyle") as QuoteStyle) ?? + defaultRomeConfig.quoteStyle, indentWidth: parseInt( searchParams.get("indentWidth") ?? defaultRomeConfig.indentWidth, ), isTypeScript: - searchParams.get( - "typescript", - ) === "true" || defaultRomeConfig.isTypeScript, + searchParams.get("typescript") === "true" || + defaultRomeConfig.isTypeScript, isJsx: searchParams.get("jsx") === "true" || defaultRomeConfig.isJsx, sourceType: - (searchParams.get( - "sourceType", - ) as SourceType) ?? defaultRomeConfig.sourceType, + (searchParams.get("sourceType") as SourceType) ?? + defaultRomeConfig.sourceType, cursorPosition: 0, }); const [playgroundState, setPlaygroundState] = useState(initState()); diff --git a/website/src/_data/env.js b/website/src/_data/env.js index 8c35171bc30..d79d41299e3 100644 --- a/website/src/_data/env.js +++ b/website/src/_data/env.js @@ -5,6 +5,6 @@ module.exports = { // Prod: pk_live_51HfdGeFXA6dCpYSpI1yUt3vEbUE0AAV0swlTUuBL7XSdzSERrqkNAsitFuTaqDxdS7HcIs5wf0PG4Mqtys01LANs00GteBJgws // Test: pk_test_51HfdGeFXA6dCpYSpScbeo75rVpehHpEPqE5QysKBwJVTnN1NjAgEuGkEHfsgQpBe1KlYwWSeTaUa5ELDSJBPKjzI00ku8lUamF STRIPE_PUBLIC: - process.env - .STRIPE_CLIENT || "pk_live_51HfdGeFXA6dCpYSpI1yUt3vEbUE0AAV0swlTUuBL7XSdzSERrqkNAsitFuTaqDxdS7HcIs5wf0PG4Mqtys01LANs00GteBJgws", + process.env.STRIPE_CLIENT || + "pk_live_51HfdGeFXA6dCpYSpI1yUt3vEbUE0AAV0swlTUuBL7XSdzSERrqkNAsitFuTaqDxdS7HcIs5wf0PG4Mqtys01LANs00GteBJgws", }; diff --git a/website/src/_includes/scripts/funding.js b/website/src/_includes/scripts/funding.js index d2824944054..3822c9e732d 100644 --- a/website/src/_includes/scripts/funding.js +++ b/website/src/_includes/scripts/funding.js @@ -557,7 +557,8 @@ for (const elem of saveElements) { // Show custom input if we hydrated it with a value that doesn't correspond with a button if ( - tipInput.value !== "" && !document.querySelector( + tipInput.value !== "" && + !document.querySelector( `.add-donation-buttons[data-price="${tipInput.value}"]`, ) ) { diff --git a/website/src/_includes/scripts/index.js b/website/src/_includes/scripts/index.js index a9db7906743..b1cebc986cd 100644 --- a/website/src/_includes/scripts/index.js +++ b/website/src/_includes/scripts/index.js @@ -174,7 +174,8 @@ class Manager { if (existing !== undefined) { const recalculated = this.calculateHeading(i, []); if ( - recalculated.start === existing.start && recalculated.end === existing.end + recalculated.start === existing.start && + recalculated.end === existing.end ) { return; } @@ -703,7 +704,7 @@ for (const scroller of heroScrollers) { } function isOverflow(index) { - return (index - activeStartIndex) >= initialItems.length; + return index - activeStartIndex >= initialItems.length; } function setActiveIndex(newActiveIndex, smooth) { From db28af09e01323200d10a84cd7aac98ad3a6d6b0 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Thu, 18 Aug 2022 09:55:12 +0200 Subject: [PATCH 3/3] Clippy --- .../expressions/parenthesized_expression.rs | 4 +- .../src/utils/binary_like_expression.rs | 52 +++++++------------ 2 files changed, 20 insertions(+), 36 deletions(-) diff --git a/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs b/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs index e28cfa46697..c894357fbfd 100644 --- a/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs +++ b/crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs @@ -23,14 +23,14 @@ impl FormatNodeRule for FormatJsParenthesizedExpressi let expression = expression?; - return write!( + write!( f, [ format_removed(&l_paren_token?), expression.format(), format_removed(&r_paren_token?) ] - ); + ) } fn needs_parentheses(&self, item: &JsParenthesizedExpression) -> bool { diff --git a/crates/rome_js_formatter/src/utils/binary_like_expression.rs b/crates/rome_js_formatter/src/utils/binary_like_expression.rs index 05a2d253233..f18cfff521f 100644 --- a/crates/rome_js_formatter/src/utils/binary_like_expression.rs +++ b/crates/rome_js_formatter/src/utils/binary_like_expression.rs @@ -56,16 +56,15 @@ use crate::prelude::*; use rome_formatter::{format_args, write, Buffer, CommentStyle, CstFormatContext}; use rome_js_syntax::{ - JsAnyExpression, JsAnyFunctionBody, JsAnyInProperty, JsArrowFunctionExpression, - JsBinaryExpression, JsBinaryOperator, JsDoWhileStatement, JsIfStatement, JsInExpression, - JsInstanceofExpression, JsLogicalExpression, JsLogicalOperator, JsParenthesizedExpression, - JsPrivateName, JsSwitchStatement, JsSyntaxKind, JsSyntaxNode, JsSyntaxToken, JsUnaryExpression, - JsWhileStatement, OperatorPrecedence, + JsAnyExpression, JsAnyInProperty, JsBinaryExpression, JsBinaryOperator, JsDoWhileStatement, + JsIfStatement, JsInExpression, JsInstanceofExpression, JsLogicalExpression, JsLogicalOperator, + JsParenthesizedExpression, JsPrivateName, JsSwitchStatement, JsSyntaxKind, JsSyntaxNode, + JsSyntaxToken, JsUnaryExpression, JsWhileStatement, OperatorPrecedence, }; use crate::parentheses::{ - is_callee, is_member_object, is_spread, is_tag, resolve_parent, ExpressionNode, - NeedsParentheses, + is_arrow_function_body, is_callee, is_member_object, is_spread, is_tag, resolve_parent, + ExpressionNode, NeedsParentheses, }; use crate::context::JsCommentStyle; @@ -294,11 +293,10 @@ impl BinaryLeftOrRightSide { _ => false, }, BinaryLeftOrRightSide::Right { parent, .. } => { - if let Ok(right) = parent.right().map(|right| right.into_resolved()) { - matches!(right, JsAnyExpression::JsxTagExpression(_)) - } else { - false - } + matches!( + parent.right().map(JsAnyExpression::into_resolved), + Ok(JsAnyExpression::JsxTagExpression(_)) + ) } } } @@ -376,7 +374,7 @@ impl Format for BinaryLeftOrRightSide { // Doesn't match prettier that only distinguishes between logical and binary let parent_has_same_kind = parent.as_ref().map_or(false, |parent| { - is_same_binary_expression_kind(binary_like_expression, &parent) + is_same_binary_expression_kind(binary_like_expression, parent) }); let left_has_same_kind = @@ -422,16 +420,14 @@ impl Format for BinaryLeftOrRightSide { } }; - let should_group = { - !(*inside_parenthesis + let should_group = !(parent_has_same_kind + || left_has_same_kind + || right_has_same_kind + || (*inside_parenthesis && matches!( binary_like_expression, JsAnyBinaryLikeExpression::JsLogicalExpression(_) - )) - && !parent_has_same_kind - && !left_has_same_kind - && !right_has_same_kind - }; + ))); if !should_break && should_group { write!(f, [group(&operator_and_right_expression)])?; @@ -586,22 +582,10 @@ impl JsAnyBinaryLikeExpression { JsSyntaxKind::JS_TEMPLATE_ELEMENT => true, JsSyntaxKind::JS_FOR_STATEMENT => true, JsSyntaxKind::JS_ARROW_FUNCTION_EXPRESSION => { - let arrow = JsArrowFunctionExpression::unwrap_cast(parent.clone()); - - arrow - .body() - .ok() - .and_then(|body| match body { - JsAnyFunctionBody::JsAnyExpression(expression) => { - Some(expression.into_resolved_syntax()) - } - JsAnyFunctionBody::JsFunctionBody(_) => None, - }) - .as_ref() - == Some(self.syntax()) + is_arrow_function_body(self.syntax(), parent) } JsSyntaxKind::JS_CONDITIONAL_EXPRESSION => { - let grand_parent = resolve_parent(&parent); + let grand_parent = resolve_parent(parent); grand_parent.map_or(false, |grand_parent| { !matches!(