fix(minifier): fix incorrect null.toString() and 1n.toString() (#8464)

This commit is contained in:
Boshen 2025-01-13 15:08:49 +00:00
parent d178360a6d
commit 1d6e84dd33
3 changed files with 17 additions and 7 deletions

View file

@ -89,10 +89,10 @@ impl<'a> ToJsString<'a> for NumericLiteral<'a> {
}
}
/// <https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-bigint.prototype.tostring>
impl<'a> ToJsString<'a> for BigIntLiteral<'a> {
fn to_js_string(&self) -> Option<Cow<'a, str>> {
// FIXME: to js bigint string
Some(Cow::Owned(self.raw.to_string()))
self.base.is_base_10().then(|| Cow::Owned(self.raw.trim_end_matches('n').to_string()))
}
}

View file

@ -314,9 +314,16 @@ impl<'a> PeepholeReplaceKnownMethods {
}
Some(ctx.ast.expression_string_literal(ce.span, Self::format_radix(i, radix), None))
}
e if e.is_literal() && args.is_empty() => {
// `null` returns type errors
Expression::BooleanLiteral(_)
| Expression::NumericLiteral(_)
| Expression::BigIntLiteral(_)
| Expression::RegExpLiteral(_)
| Expression::StringLiteral(_)
if args.is_empty() =>
{
use oxc_ecmascript::ToJsString;
e.to_js_string().map(|s| ctx.ast.expression_string_literal(ce.span, s, None))
object.to_js_string().map(|s| ctx.ast.expression_string_literal(ce.span, s, None))
}
_ => None,
}
@ -1209,7 +1216,10 @@ mod test {
test("123 .toString()", "'123';");
test("NaN.toString()", "'NaN';");
test("Infinity.toString()", "'Infinity';");
// test("/a\\\\b/ig.toString()", "'/a\\\\\\\\b/ig';");
test("1n.toString()", "'1'");
test_same("254n.toString(16);"); // unimplemented
// test("/a\\\\b/ig.toString()", "'/a\\\\\\\\b/ig';");
test_same("null.toString()"); // type error
test("100 .toString(0)", "100 .toString(0)");
test("100 .toString(1)", "100 .toString(1)");

View file

@ -33,9 +33,9 @@ fn test() {
ast.alloc(ast.object_expression(SPAN, ast.vec(), None)),
));
let joined = array2.array_join(Some("_"));
assert_eq!(joined, Some("__42_foo_true_42n_,,42,foo,true,42n_[object Object]".to_string()));
assert_eq!(joined, Some("__42_foo_true_42_,,42,foo,true,42_[object Object]".to_string()));
let joined2 = array2.array_join(None);
// By default, in `Array.prototype.toString`, the separator is a comma. However, in `Array.prototype.join`, the separator is none if not given.
assert_eq!(joined2, Some(",,42,foo,true,42n,,,42,foo,true,42n,[object Object]".to_string()));
assert_eq!(joined2, Some(",,42,foo,true,42,,,42,foo,true,42,[object Object]".to_string()));
}