diff --git a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs index 9cd97b2ed5a9c8..aadea7a4d1dd86 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs @@ -1,6 +1,5 @@ use std::cmp::Ordering; use std::ops::Neg; -use std::str::FromStr; use num_bigint::BigInt; use oxc_ast::ast::*; @@ -188,22 +187,17 @@ impl<'a> PeepholeFoldConstants { _ => None, }, UnaryOperator::BitwiseNot => match &mut expr.argument { - Expression::BigIntLiteral(n) => n - .base - .is_base_10() - .then(|| { - // Use `unwrap`, because we know it's a valid BigInt literal, which ends with 'n'. - let value = BigInt::from_str(n.raw.as_str().strip_suffix('n').unwrap()); - value.ok().map(|value| { - let value = !value; - ctx.ast.expression_big_int_literal( - SPAN, - value.to_string() + "n", - BigintBase::Decimal, - ) - }) + Expression::BigIntLiteral(n) => { + let value = ctx.get_string_bigint_value(n.raw.as_str().trim_end_matches('n')); + value.map(|value| { + let value = !value; + ctx.ast.expression_big_int_literal( + SPAN, + value.to_string() + "n", + BigintBase::Decimal, + ) }) - .unwrap_or(None), + } Expression::NumericLiteral(n) => is_within_i32_range(n.value).then(|| { let value = !n.value.to_js_int_32(); ctx.ast.expression_numeric_literal( @@ -222,25 +216,17 @@ impl<'a> PeepholeFoldConstants { UnaryOperator::UnaryNegation if un.argument.is_big_int_literal() => { // `~-1n` -> `0n` if let Expression::BigIntLiteral(n) = &mut un.argument { - n.base - .is_base_10() - .then(|| { - // The value is a valid BigInt literal, which ends with 'n'. - let value = BigInt::from_str( - n.raw.as_str().strip_suffix('n').unwrap(), - ); - value - .ok() - .and_then(|value| value.checked_sub(&BigInt::from(1))) - .map(|value| { - ctx.ast.expression_big_int_literal( - SPAN, - value.neg().to_string() + "n", - BigintBase::Decimal, - ) - }) - }) - .unwrap_or(None) + let value = ctx + .get_string_bigint_value(n.raw.as_str().trim_end_matches('n')); + value.and_then(|value| value.checked_sub(&BigInt::from(1))).map( + |value| { + ctx.ast.expression_big_int_literal( + SPAN, + value.neg().to_string() + "n", + BigintBase::Decimal, + ) + }, + ) } else { None } @@ -1400,9 +1386,8 @@ mod test { test("~-1n", "0n"); test("~~1n", "1n"); - // The num_bigint does not natively parse non-decimal numbers, or its format is not JS-like. - // test("~0x3n", "-4n"); - // test("~0b11n", "-4n"); + test("~0x3n", "-4n"); + test("~0b11n", "-4n"); } #[test]