From bb61f10399e5243f57da0eeab2e18aac8ef6e361 Mon Sep 17 00:00:00 2001 From: Boshen Date: Fri, 1 Dec 2023 21:29:56 +0800 Subject: [PATCH] feat(prettier): handle parens for `(x % y) % z` (#1603) --- crates/oxc_prettier/src/binaryish.rs | 30 ++++++++++++++------- crates/oxc_prettier/src/needs_parens.rs | 6 +++++ tasks/prettier_conformance/prettier.snap.md | 3 +-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/crates/oxc_prettier/src/binaryish.rs b/crates/oxc_prettier/src/binaryish.rs index 3b56a778e..260a50715 100644 --- a/crates/oxc_prettier/src/binaryish.rs +++ b/crates/oxc_prettier/src/binaryish.rs @@ -84,26 +84,36 @@ impl BinaryishOperator { return false; } - if matches!(parent_op, Self::BinaryOperator(op) if op == BinaryOperator::Exponential) { + let Self::BinaryOperator(op) = self else { return true }; + + let Self::BinaryOperator(parent_op) = parent_op else { return true }; + + // ** is right-associative + // x ** y ** z --> x ** (y ** z) + if parent_op == BinaryOperator::Exponential { return false; } - if matches!(parent_op, Self::BinaryOperator(op) if op.is_equality()) - && matches!(self, Self::BinaryOperator(op) if op.is_equality()) + // x == y == z --> (x == y) == z + if parent_op.is_equality() && op.is_equality() { + return false; + } + + // x * y % z --> (x * y) % z + if (op == BinaryOperator::Remainder && parent_op.is_multiplicative()) + || (parent_op == BinaryOperator::Remainder && op.is_multiplicative()) { return false; } - if self != parent_op - && matches!(parent_op, Self::BinaryOperator(op) if op.is_multiplicative()) - && matches!(self, Self::BinaryOperator(op) if op.is_multiplicative()) - { + // x * y / z --> (x * y) / z + // x / y * z --> (x / y) * z + if op != parent_op && parent_op.is_multiplicative() && op.is_multiplicative() { return false; } - if matches!(parent_op, Self::BinaryOperator(op) if op.is_bitshift()) - && matches!(self, Self::BinaryOperator(op) if op.is_bitshift()) - { + // x << y << z --> (x << y) << z + if parent_op.is_bitshift() && op.is_bitshift() { return false; } diff --git a/crates/oxc_prettier/src/needs_parens.rs b/crates/oxc_prettier/src/needs_parens.rs index 88adf7e52..6aaf80fb6 100644 --- a/crates/oxc_prettier/src/needs_parens.rs +++ b/crates/oxc_prettier/src/needs_parens.rs @@ -452,6 +452,12 @@ impl<'a> Prettier<'a> { return true; } + if parent_precedence < precedence + && matches!(operator, BinaryishOperator::BinaryOperator(op) if op == BinaryOperator::Remainder) + { + return matches!(parent_operator, BinaryishOperator::BinaryOperator(op) if matches!(op, BinaryOperator::Addition | BinaryOperator::Subtraction)); + } + // Add parenthesis when working with bitwise operators // It's not strictly needed but helps with code understanding if matches!(parent_kind, AstKind::BinaryExpression(binary_expr) if binary_expr.operator.is_bitwise()) diff --git a/tasks/prettier_conformance/prettier.snap.md b/tasks/prettier_conformance/prettier.snap.md index 9c8b800f2..f4add2de7 100644 --- a/tasks/prettier_conformance/prettier.snap.md +++ b/tasks/prettier_conformance/prettier.snap.md @@ -1,4 +1,4 @@ -Compatibility: 212/561 (37.79%) +Compatibility: 215/561 (38.32%) # Failed @@ -75,7 +75,6 @@ Compatibility: 212/561 (37.79%) * binary-expressions/inline-jsx.js * binary-expressions/inline-object-array.js * binary-expressions/jsx_parent.js -* binary-expressions/math.js * binary-expressions/return.js * binary-expressions/short-right.js * binary-expressions/test.js