From 784796d8693f2a52147b01082afd7be68d837cd3 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Sat, 9 Aug 2025 14:46:20 +0000 Subject: [PATCH] feat(minifier): fold `(!0).toString()` to `true` (#12938) --- .../src/constant_evaluation/call_expr.rs | 16 +++++++--------- .../src/constant_evaluation/value.rs | 4 ++++ .../src/peephole/replace_known_methods.rs | 2 ++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs b/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs index 7de4ca1c1ce90..9441e2b13ad98 100644 --- a/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs +++ b/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs @@ -324,16 +324,14 @@ fn try_fold_to_string<'a>( let result = format_radix(i, radix); Some(ConstantValue::String(Cow::Owned(result))) } - // `null` returns type errors - Expression::BooleanLiteral(_) - | Expression::NumericLiteral(_) - | Expression::BigIntLiteral(_) - | Expression::RegExpLiteral(_) - | Expression::StringLiteral(_) - if args.is_empty() => - { - object.to_js_string(ctx).map(ConstantValue::String) + Expression::RegExpLiteral(lit) if args.is_empty() => { + lit.to_js_string(ctx).map(ConstantValue::String) } + e if args.is_empty() => e + .evaluate_value(ctx) + // `null` and `undefined` returns type errors + .filter(|v| !v.is_undefined() && !v.is_null()) + .and_then(|v| v.to_js_string(ctx).map(ConstantValue::String)), _ => None, } } diff --git a/crates/oxc_ecmascript/src/constant_evaluation/value.rs b/crates/oxc_ecmascript/src/constant_evaluation/value.rs index 994a3e50ce6d9..40076948a5e48 100644 --- a/crates/oxc_ecmascript/src/constant_evaluation/value.rs +++ b/crates/oxc_ecmascript/src/constant_evaluation/value.rs @@ -36,6 +36,10 @@ impl<'a> ConstantValue<'a> { matches!(self, Self::Undefined) } + pub fn is_null(&self) -> bool { + matches!(self, Self::Null) + } + pub fn into_string(self) -> Option> { match self { Self::String(s) => Some(s), diff --git a/crates/oxc_minifier/src/peephole/replace_known_methods.rs b/crates/oxc_minifier/src/peephole/replace_known_methods.rs index 2d4602b5c8c0a..5ed65b071e137 100644 --- a/crates/oxc_minifier/src/peephole/replace_known_methods.rs +++ b/crates/oxc_minifier/src/peephole/replace_known_methods.rs @@ -1486,6 +1486,8 @@ mod test { test("x = false['toString']()", "x = 'false';"); test("x = false.toString()", "x = 'false';"); test("x = true.toString()", "x = 'true';"); + test("x = (!0).toString()", "x = 'true';"); + test("x = (!1).toString()", "x = 'false';"); test("x = 'xy'.toString()", "x = 'xy';"); test("x = 0 .toString()", "x = '0';"); test("x = 123 .toString()", "x = '123';");