diff --git a/crates/oxc_minifier/src/peephole/minimize_conditions.rs b/crates/oxc_minifier/src/peephole/minimize_conditions.rs index 2c624985fbfc1..ae1f91a310e97 100644 --- a/crates/oxc_minifier/src/peephole/minimize_conditions.rs +++ b/crates/oxc_minifier/src/peephole/minimize_conditions.rs @@ -1,6 +1,9 @@ use oxc_allocator::TakeIn; use oxc_ast::ast::*; -use oxc_ecmascript::constant_evaluation::{ConstantEvaluation, ConstantValue, DetermineValueType}; +use oxc_ecmascript::{ + constant_evaluation::{ConstantEvaluation, ConstantValue, DetermineValueType}, + side_effects::MayHaveSideEffects, +}; use oxc_span::GetSpan; use oxc_syntax::es_target::ESTarget; @@ -135,28 +138,30 @@ impl<'a> PeepholeOptimizations { _ => {} } } - match &mut e.right { - Expression::BooleanLiteral(b) if left.is_boolean() => { - match e.operator { - BinaryOperator::Inequality | BinaryOperator::StrictInequality => { - e.operator = BinaryOperator::Equality; - b.value = !b.value; - } - BinaryOperator::StrictEquality => { - e.operator = BinaryOperator::Equality; - } - BinaryOperator::Equality => {} - _ => return None, - } - Some(if b.value { - e.left.take_in(ctx.ast) - } else { - let argument = e.left.take_in(ctx.ast); - ctx.ast.expression_unary(e.span, UnaryOperator::LogicalNot, argument) - }) + if !left.is_boolean() { + return None; + } + if e.right.may_have_side_effects(ctx) { + return None; + } + let mut b = e.right.evaluate_value(ctx).and_then(ConstantValue::into_boolean)?; + match e.operator { + BinaryOperator::Inequality | BinaryOperator::StrictInequality => { + e.operator = BinaryOperator::Equality; + b = !b; } - _ => None, + BinaryOperator::StrictEquality => { + e.operator = BinaryOperator::Equality; + } + BinaryOperator::Equality => {} + _ => return None, } + Some(if b { + e.left.take_in(ctx.ast) + } else { + let argument = e.left.take_in(ctx.ast); + ctx.ast.expression_unary(e.span, UnaryOperator::LogicalNot, argument) + }) } /// Compress `foo == true` into `foo == 1`. @@ -1468,4 +1473,12 @@ mod test { test("v = x == !1", "v = x == 0"); test("v = x != !1", "v = x != 0"); } + + #[test] + fn try_minimize_binary() { + test("f(!a === !0)", "f(!a)"); + test("f(!a === !1)", "f(!!a)"); + test("f(!a === true)", "f(!a)"); + test("f(!a === false)", "f(!!a)"); + } }