From 7da3f52485062eb23c719e1236b2fee90c228bdd Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 13 Oct 2023 01:07:00 -0500 Subject: [PATCH] feat(es/minifier): Evaluate more `toFixed` expressions (#8109) --- Cargo.lock | 4 +- crates/swc_ecma_minifier/Cargo.toml | 2 +- .../src/compress/pure/evaluate.rs | 31 +---- .../tests/fixture/issues/2257/full/output.js | 2 +- .../tests/fixture/issues/6957/1/output.js | 32 ++--- .../tests/fixture/issues/6957/2/output.js | 4 +- .../issues/6957/number-tostring/output.js | 118 +++++++++--------- .../compress/evaluate/issue_2207_1/output.js | 2 +- .../swc_ecma_transforms_typescript/Cargo.toml | 2 +- 9 files changed, 86 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c612928603f..c0381173d04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3153,9 +3153,9 @@ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "ryu-js" -version = "0.2.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6518fc26bced4d53678a22d6e423e9d8716377def84545fe328236e3af070e7f" +checksum = "4950d85bc52415f8432144c97c4791bd0c4f7954de32a7270ee9cccd3c22b12b" [[package]] name = "same-file" diff --git a/crates/swc_ecma_minifier/Cargo.toml b/crates/swc_ecma_minifier/Cargo.toml index ee06e8a630e..1d70a1b92f8 100644 --- a/crates/swc_ecma_minifier/Cargo.toml +++ b/crates/swc_ecma_minifier/Cargo.toml @@ -45,7 +45,7 @@ radix_fmt = "=1.0.0" rayon = { version = "1.7.0", optional = true } regex = "1.5.3" rustc-hash = "1.1.0" -ryu-js = "0.2.2" +ryu-js = "1.0.0" serde = { version = "1.0.118", features = ["derive"] } serde_json = "1.0.61" tracing = "0.1.37" diff --git a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs index 3e56ac54932..a1bc165fd0a 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs @@ -330,7 +330,7 @@ impl Pure<'_> { // 3. Assert: If fractionDigits is undefined, then f is 0. .map_or(Some(0f64), |arg| eval_as_number(&self.expr_ctx, &arg.expr)) { - let f = precision.trunc() as usize; + let f = precision.trunc() as u8; // 4. If f is not finite, throw a RangeError exception. // 5. If f < 0 or f > 100, throw a RangeError exception. @@ -341,33 +341,8 @@ impl Pure<'_> { return; } - // 6. If x is not finite, return Number::toString(x, 10). - - let x = { - let x = num.value; - // 7. Set x to ℝ(x). - if x == -0. { - 0. - } else { - x - } - }; - // 8. Let s be the empty String. - // 9. If x < 0, then a. Set s to "-". b. Set x to -x. - // 10. If x ≥ 10**21, then a. Let m be ! ToString(𝔽(x)). - let value = if x >= 1e21 || x <= -1e21 { - format!("{:e}", x).replace('e', "e+") - } else { - // 11. Else, - - if x.fract() != 0. || f != 0 { - // TODO: rust built-in format cannot handle ecma262 `1.25.toFixed(1)` - - return; - } else { - format!("{:.*}", f, x) - } - }; + let mut buffer = ryu_js::Buffer::new(); + let value = buffer.format_to_fixed(num.value, f); self.changed = true; report_change!( diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js index 6818f6ec45e..1921815ec17 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js @@ -6018,7 +6018,7 @@ $({ target: "Number", proto: !0, - forced: nativeToFixed && ("0.000" !== 0.00008.toFixed(3) || "1" !== 0.9.toFixed(0) || "1.25" !== 1.255.toFixed(2)) || !fails(function() { + forced: !fails(function() { nativeToFixed.call({}); }) }, { diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6957/1/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6957/1/output.js index 55ce3dee1d7..22c7a794b40 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/6957/1/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6957/1/output.js @@ -1,19 +1,19 @@ export function foo() { - alert(1..toFixed(1)); + alert("1.0"); alert("0"); - alert(0..toFixed(1)); - alert(0..toFixed(2)); - alert(0..toFixed(3)); - alert(10..toFixed(1)); - alert(20..toFixed(2)); - alert(30..toFixed(3)); - alert(100..toFixed(1)); - alert(100..toFixed(2)); - alert(100..toFixed(3)); - alert(110..toFixed(1)); - alert(110..toFixed(2)); - alert(110..toFixed(3)); - alert(110..toFixed(4)); - alert(1110..toFixed(4)); - alert(11110..toFixed(4)); + alert("0.0"); + alert("0.00"); + alert("0.000"); + alert("10.0"); + alert("20.00"); + alert("30.000"); + alert("100.0"); + alert("100.00"); + alert("100.000"); + alert("110.0"); + alert("110.00"); + alert("110.000"); + alert("110.0000"); + alert("1110.0000"); + alert("11110.0000"); } diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6957/2/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6957/2/output.js index c6090de6014..82ffd2f03a8 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/6957/2/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6957/2/output.js @@ -1,2 +1,2 @@ -assertEquals("1", 0.5.toFixed(0), "0.5.toFixed(0)"); -assertEquals("-1", (-0.5).toFixed(0), "(-0.5).toFixed(0)"); +assertEquals("1", "1", "0.5.toFixed(0)"); +assertEquals("-1", "-1", "(-0.5).toFixed(0)"); diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6957/number-tostring/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6957/number-tostring/output.js index 161574fcaed..fd0b0d52752 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/6957/number-tostring/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6957/number-tostring/output.js @@ -120,74 +120,74 @@ assertEquals("NaN", NaN.toFixed(2)); assertEquals("Infinity", (1 / 0).toFixed(2)); assertEquals("-Infinity", (-1 / 0).toFixed(2)); assertEquals("1.1111111111111111e+21", "1.1111111111111111e+21"); -assertEquals("0.1", 0.1.toFixed(1)); -assertEquals("0.10", 0.1.toFixed(2)); -assertEquals("0.100", 0.1.toFixed(3)); -assertEquals("0.01", 0.01.toFixed(2)); -assertEquals("0.010", 0.01.toFixed(3)); -assertEquals("0.0100", 0.01.toFixed(4)); -assertEquals("0.00", 0.001.toFixed(2)); -assertEquals("0.001", 0.001.toFixed(3)); -assertEquals("0.0010", 0.001.toFixed(4)); -assertEquals("1.0000", 1..toFixed(4)); -assertEquals("1.0", 1..toFixed(1)); +assertEquals("0.1", "0.1"); +assertEquals("0.10", "0.10"); +assertEquals("0.100", "0.100"); +assertEquals("0.01", "0.01"); +assertEquals("0.010", "0.010"); +assertEquals("0.0100", "0.0100"); +assertEquals("0.00", "0.00"); +assertEquals("0.001", "0.001"); +assertEquals("0.0010", "0.0010"); +assertEquals("1.0000", "1.0000"); +assertEquals("1.0", "1.0"); assertEquals("1", "1"); assertEquals("12", "12"); -assertEquals("1", 1.1.toFixed(0)); -assertEquals("12", 12.1.toFixed(0)); -assertEquals("1", 1.12.toFixed(0)); -assertEquals("12", 12.12.toFixed(0)); -assertEquals("0.0000006", 0.0000006.toFixed(7)); -assertEquals("0.00000006", 0.00000006.toFixed(8)); -assertEquals("0.000000060", 0.00000006.toFixed(9)); -assertEquals("0.0000000600", 0.00000006.toFixed(10)); +assertEquals("1", "1"); +assertEquals("12", "12"); +assertEquals("1", "1"); +assertEquals("12", "12"); +assertEquals("0.0000006", "0.0000006"); +assertEquals("0.00000006", "0.00000006"); +assertEquals("0.000000060", "0.000000060"); +assertEquals("0.0000000600", "0.0000000600"); assertEquals("0", "0"); -assertEquals("0.0", 0..toFixed(1)); -assertEquals("0.00", 0..toFixed(2)); +assertEquals("0.0", "0.0"); +assertEquals("0.00", "0.00"); assertEquals("-1.1111111111111111e+21", "-1.1111111111111111e+21"); -assertEquals("-0.1", (-0.1).toFixed(1)); -assertEquals("-0.10", (-0.1).toFixed(2)); -assertEquals("-0.100", (-0.1).toFixed(3)); -assertEquals("-0.01", (-0.01).toFixed(2)); -assertEquals("-0.010", (-0.01).toFixed(3)); -assertEquals("-0.0100", (-0.01).toFixed(4)); -assertEquals("-0.00", (-0.001).toFixed(2)); -assertEquals("-0.001", (-0.001).toFixed(3)); -assertEquals("-0.0010", (-0.001).toFixed(4)); -assertEquals("-1.0000", (-1).toFixed(4)); -assertEquals("-1.0", (-1).toFixed(1)); +assertEquals("-0.1", "-0.1"); +assertEquals("-0.10", "-0.10"); +assertEquals("-0.100", "-0.100"); +assertEquals("-0.01", "-0.01"); +assertEquals("-0.010", "-0.010"); +assertEquals("-0.0100", "-0.0100"); +assertEquals("-0.00", "-0.00"); +assertEquals("-0.001", "-0.001"); +assertEquals("-0.0010", "-0.0010"); +assertEquals("-1.0000", "-1.0000"); +assertEquals("-1.0", "-1.0"); assertEquals("-1", "-1"); -assertEquals("-1", (-1.1).toFixed(0)); -assertEquals("-12", (-12.1).toFixed(0)); -assertEquals("-1", (-1.12).toFixed(0)); -assertEquals("-12", (-12.12).toFixed(0)); -assertEquals("-0.0000006", (-0.0000006).toFixed(7)); -assertEquals("-0.00000006", (-0.00000006).toFixed(8)); -assertEquals("-0.000000060", (-0.00000006).toFixed(9)); -assertEquals("-0.0000000600", (-0.00000006).toFixed(10)); +assertEquals("-1", "-1"); +assertEquals("-12", "-12"); +assertEquals("-1", "-1"); +assertEquals("-12", "-12"); +assertEquals("-0.0000006", "-0.0000006"); +assertEquals("-0.00000006", "-0.00000006"); +assertEquals("-0.000000060", "-0.000000060"); +assertEquals("-0.0000000600", "-0.0000000600"); assertEquals("0", "0"); -assertEquals("0.0", (-0).toFixed(1)); -assertEquals("0.00", (-0).toFixed(2)); +assertEquals("0.0", "0.0"); +assertEquals("0.00", "0.00"); assertEquals("1000", "1000"); -assertEquals("0", 0.00001.toFixed()); -assertEquals("0.00001", 0.00001.toFixed(5)); -assertEquals("0.00000000000000000010", 0.0000000000000000001.toFixed(20)); -assertEquals("0.00001000000000000", 0.00001.toFixed(17)); -assertEquals("1.00000000000000000", 1..toFixed(17)); -assertEquals("1000000000000000128", "1000000000000000128"); -assertEquals("100000000000000128.0", 100000000000000128..toFixed(1)); -assertEquals("10000000000000128.00", 10000000000000128..toFixed(2)); -assertEquals("10000000000000128.00000000000000000000", 10000000000000128..toFixed(20)); assertEquals("0", "0"); -assertEquals("-42.000", (-42).toFixed(3)); +assertEquals("0.00001", "0.00001"); +assertEquals("0.00000000000000000010", "0.00000000000000000010"); +assertEquals("0.00001000000000000", "0.00001000000000000"); +assertEquals("1.00000000000000000", "1.00000000000000000"); +assertEquals("1000000000000000128", "1000000000000000128"); +assertEquals("100000000000000128.0", "100000000000000128.0"); +assertEquals("10000000000000128.00", "10000000000000128.00"); +assertEquals("10000000000000128.00000000000000000000", "10000000000000128.00000000000000000000"); +assertEquals("0", "0"); +assertEquals("-42.000", "-42.000"); assertEquals("-1000000000000000128", "-1000000000000000128"); -assertEquals("-0.00000000000000000010", (-0.0000000000000000001).toFixed(20)); -assertEquals("0.12312312312312299889", 0.123123123123123.toFixed(20)); -assertEquals("1", 0.5.toFixed(0), "0.5.toFixed(0)"); -assertEquals("-1", (-0.5).toFixed(0), "(-0.5).toFixed(0)"); -assertEquals("1.3", 1.25.toFixed(1), "1.25.toFixed(1)"); -assertEquals("234.2040", 234.20405.toFixed(4), "234.2040.toFixed(4)"); -assertEquals("234.2041", 234.2040506.toFixed(4)); +assertEquals("-0.00000000000000000010", "-0.00000000000000000010"); +assertEquals("0.12312312312312299889", "0.12312312312312299889"); +assertEquals("1", "1", "0.5.toFixed(0)"); +assertEquals("-1", "-1", "(-0.5).toFixed(0)"); +assertEquals("1.3", "1.3", "1.25.toFixed(1)"); +assertEquals("234.2040", "234.2040", "234.2040.toFixed(4)"); +assertEquals("234.2041", "234.2041"); assertEquals("1e+0", "1e+0"); assertEquals("1.1e+1", "1.1e+1"); assertEquals("1.12e+2", "1.12e+2"); diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/issue_2207_1/output.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/issue_2207_1/output.js index 938065d16e5..5ad7a3669c1 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/issue_2207_1/output.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/issue_2207_1/output.js @@ -2,4 +2,4 @@ console.log("A"); console.log(7); console.log(0.32999315767856785); console.log(1.2543732512566947); -console.log(1.6093984514472044.toFixed(15)); +console.log("1.609398451447204"); diff --git a/crates/swc_ecma_transforms_typescript/Cargo.toml b/crates/swc_ecma_transforms_typescript/Cargo.toml index 11add503350..293ea1f74b2 100644 --- a/crates/swc_ecma_transforms_typescript/Cargo.toml +++ b/crates/swc_ecma_transforms_typescript/Cargo.toml @@ -15,7 +15,7 @@ bench = false [dependencies] serde = { version = "1.0.118", features = ["derive"] } -ryu-js = "0.2.2" +ryu-js = "1.0.0" swc_atoms = { version = "0.6.0", path = "../swc_atoms" } swc_common = { version = "0.33.0", path = "../swc_common" } swc_ecma_ast = { version = "0.110.0", path = "../swc_ecma_ast" }