From e231ad03951eccd8cb400cbf8181e2184a5bb9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 2 Jun 2024 11:32:52 +0900 Subject: [PATCH 1/8] fix --- crates/swc_ecma_utils/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/swc_ecma_utils/src/lib.rs b/crates/swc_ecma_utils/src/lib.rs index aa1292659b29..635c9a098c54 100644 --- a/crates/swc_ecma_utils/src/lib.rs +++ b/crates/swc_ecma_utils/src/lib.rs @@ -979,7 +979,13 @@ pub trait ExprExt { match *expr { Expr::Lit(ref l) => match *l { Lit::Str(Str { ref value, .. }) => Known(Cow::Borrowed(value)), - Lit::Num(ref n) => Known(format!("{}", n).into()), + Lit::Num(ref n) => { + if n.value == -0.0 { + return Known(Cow::Borrowed("0")); + } + + Known(format!("{}", n).into()) + } Lit::Bool(Bool { value: true, .. }) => Known(Cow::Borrowed("true")), Lit::Bool(Bool { value: false, .. }) => Known(Cow::Borrowed("false")), Lit::Null(..) => Known(Cow::Borrowed("null")), From 93f2d1dd9930e473919984ad3b8cfba7cf575474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 2 Jun 2024 11:33:02 +0900 Subject: [PATCH 2/8] Add a test --- crates/swc_ecma_minifier/tests/exec.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/swc_ecma_minifier/tests/exec.rs b/crates/swc_ecma_minifier/tests/exec.rs index 8ac36c3f02e1..58793b984acc 100644 --- a/crates/swc_ecma_minifier/tests/exec.rs +++ b/crates/swc_ecma_minifier/tests/exec.rs @@ -11311,3 +11311,12 @@ fn issue_8982_2() { ", ); } + +#[test] +fn issue_9010() { + run_default_exec_test( + r#" + console.log(-0 + []) + "#, + ); +} From 0eac614a08957d2560842c8667c14acdfd0ea66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 2 Jun 2024 13:14:36 +0900 Subject: [PATCH 3/8] Dep --- Cargo.toml | 1 + crates/swc_ecma_utils/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 1ef222523e6d..1c64ebd87427 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,6 +92,7 @@ resolver = "2" relative-path = "1.6.1" reqwest = "0.11.14" rustc-hash = "1.1.0" + ryu = "1.0.18" ryu-js = "1.0.0" scoped-tls = "1.0.1" semver = "1.0.20" diff --git a/crates/swc_ecma_utils/Cargo.toml b/crates/swc_ecma_utils/Cargo.toml index 7416e593d386..dbd6caa14b27 100644 --- a/crates/swc_ecma_utils/Cargo.toml +++ b/crates/swc_ecma_utils/Cargo.toml @@ -25,6 +25,7 @@ num_cpus = { workspace = true } once_cell = { workspace = true } rayon = { workspace = true, optional = true } rustc-hash = { workspace = true } +ryu = { workspace = true } tracing = { workspace = true } unicode-id = { workspace = true } From 06cba64d90458c8bf509e285655fc392c6654296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 2 Jun 2024 13:14:42 +0900 Subject: [PATCH 4/8] cargo lockfile --- Cargo.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e71313fe71f..66e5cf4be47a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3225,9 +3225,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "ryu-js" @@ -4896,6 +4896,7 @@ dependencies = [ "once_cell", "rayon", "rustc-hash", + "ryu", "stacker", "swc_atoms", "swc_common", From 96c362c0501b70e38d4eac8c5ab1393ad5dad804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 2 Jun 2024 13:15:36 +0900 Subject: [PATCH 5/8] Use ryu --- crates/swc_ecma_utils/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/swc_ecma_utils/src/lib.rs b/crates/swc_ecma_utils/src/lib.rs index 635c9a098c54..f61988148361 100644 --- a/crates/swc_ecma_utils/src/lib.rs +++ b/crates/swc_ecma_utils/src/lib.rs @@ -984,7 +984,8 @@ pub trait ExprExt { return Known(Cow::Borrowed("0")); } - Known(format!("{}", n).into()) + let mut buffer = ryu::Buffer::new(); + Known(Cow::Owned(buffer.format(n.value).to_string())) } Lit::Bool(Bool { value: true, .. }) => Known(Cow::Borrowed("true")), Lit::Bool(Bool { value: false, .. }) => Known(Cow::Borrowed("false")), From ef0e4dfba825245de59572e6268d842dd8ffd85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 2 Jun 2024 17:05:08 +0900 Subject: [PATCH 6/8] ryu-js --- Cargo.lock | 2 +- Cargo.toml | 1 - crates/swc_ecma_utils/Cargo.toml | 2 +- crates/swc_ecma_utils/src/lib.rs | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66e5cf4be47a..e542c2e075e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4896,7 +4896,7 @@ dependencies = [ "once_cell", "rayon", "rustc-hash", - "ryu", + "ryu-js", "stacker", "swc_atoms", "swc_common", diff --git a/Cargo.toml b/Cargo.toml index 1c64ebd87427..1ef222523e6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,7 +92,6 @@ resolver = "2" relative-path = "1.6.1" reqwest = "0.11.14" rustc-hash = "1.1.0" - ryu = "1.0.18" ryu-js = "1.0.0" scoped-tls = "1.0.1" semver = "1.0.20" diff --git a/crates/swc_ecma_utils/Cargo.toml b/crates/swc_ecma_utils/Cargo.toml index dbd6caa14b27..7a2c97e1d637 100644 --- a/crates/swc_ecma_utils/Cargo.toml +++ b/crates/swc_ecma_utils/Cargo.toml @@ -25,7 +25,7 @@ num_cpus = { workspace = true } once_cell = { workspace = true } rayon = { workspace = true, optional = true } rustc-hash = { workspace = true } -ryu = { workspace = true } +ryu-js = { workspace = true } tracing = { workspace = true } unicode-id = { workspace = true } diff --git a/crates/swc_ecma_utils/src/lib.rs b/crates/swc_ecma_utils/src/lib.rs index f61988148361..0facc828b02a 100644 --- a/crates/swc_ecma_utils/src/lib.rs +++ b/crates/swc_ecma_utils/src/lib.rs @@ -984,7 +984,7 @@ pub trait ExprExt { return Known(Cow::Borrowed("0")); } - let mut buffer = ryu::Buffer::new(); + let mut buffer = ryu_js::Buffer::new(); Known(Cow::Owned(buffer.format(n.value).to_string())) } Lit::Bool(Bool { value: true, .. }) => Known(Cow::Borrowed("true")), From ff55e7d953aec2483304755e5d4eb7552ed90f64 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Sun, 2 Jun 2024 16:08:42 +0800 Subject: [PATCH 7/8] chore: extract `ToJsString` --- crates/swc_ecma_utils/src/lib.rs | 5 +++-- crates/swc_ecma_utils/src/number.rs | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 crates/swc_ecma_utils/src/number.rs diff --git a/crates/swc_ecma_utils/src/lib.rs b/crates/swc_ecma_utils/src/lib.rs index 0facc828b02a..f69df5749e2c 100644 --- a/crates/swc_ecma_utils/src/lib.rs +++ b/crates/swc_ecma_utils/src/lib.rs @@ -13,6 +13,7 @@ pub extern crate swc_common; use std::{borrow::Cow, hash::Hash, num::FpCategory, ops::Add}; +use number::ToJsString; use rustc_hash::FxHashMap; use swc_atoms::JsWord; use swc_common::{ @@ -50,6 +51,7 @@ mod value; pub mod var; mod node_ignore_span; +pub mod number; pub mod stack_size; pub use node_ignore_span::NodeIgnoringSpan; @@ -984,8 +986,7 @@ pub trait ExprExt { return Known(Cow::Borrowed("0")); } - let mut buffer = ryu_js::Buffer::new(); - Known(Cow::Owned(buffer.format(n.value).to_string())) + Known(Cow::Owned(n.value.to_js_string())) } Lit::Bool(Bool { value: true, .. }) => Known(Cow::Borrowed("true")), Lit::Bool(Bool { value: false, .. }) => Known(Cow::Borrowed("false")), diff --git a/crates/swc_ecma_utils/src/number.rs b/crates/swc_ecma_utils/src/number.rs new file mode 100644 index 000000000000..54d0ae892f38 --- /dev/null +++ b/crates/swc_ecma_utils/src/number.rs @@ -0,0 +1,11 @@ +/// +pub trait ToJsString { + fn to_js_string(&self) -> String; +} + +impl ToJsString for f64 { + fn to_js_string(&self) -> String { + let mut buffer = ryu_js::Buffer::new(); + buffer.format(*self).to_string() + } +} From fb3f764cad5f3db3af647505d334df096e1ddfab Mon Sep 17 00:00:00 2001 From: magic-akari Date: Sun, 2 Jun 2024 16:21:57 +0800 Subject: [PATCH 8/8] chore: use `number::ToJsString` --- crates/swc_ecma_minifier/src/compress/pure/evaluate.rs | 6 +++--- crates/swc_ecma_transforms_typescript/src/ts_enum.rs | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs index d6f6e1db1477..bd2ee0210c85 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs @@ -1,7 +1,7 @@ use radix_fmt::Radix; use swc_common::{util::take::Take, Spanned, SyntaxContext}; use swc_ecma_ast::*; -use swc_ecma_utils::{undefined, ExprExt, IsEmpty, Value}; +use swc_ecma_utils::{number::ToJsString, undefined, ExprExt, IsEmpty, Value}; use super::Pure; use crate::compress::util::{eval_as_number, is_pure_undefined_or_null}; @@ -382,7 +382,7 @@ impl Pure<'_> { if args.first().is_none() { // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.prototype.toprecision // 2. If precision is undefined, return ! ToString(x). - let value = ryu_js::Buffer::new().format(num.value).to_string().into(); + let value = num.value.to_js_string().into(); self.changed = true; report_change!( @@ -478,7 +478,7 @@ impl Pure<'_> { .map_or(Some(10f64), |arg| eval_as_number(&self.expr_ctx, &arg.expr)) { if base.trunc() == 10. { - let value = ryu_js::Buffer::new().format(num.value).to_string().into(); + let value = num.value.to_js_string().into(); *e = Expr::Lit(Lit::Str(Str { span: e.span(), raw: None, diff --git a/crates/swc_ecma_transforms_typescript/src/ts_enum.rs b/crates/swc_ecma_transforms_typescript/src/ts_enum.rs index d6365c4846e4..62825ed7b042 100644 --- a/crates/swc_ecma_transforms_typescript/src/ts_enum.rs +++ b/crates/swc_ecma_transforms_typescript/src/ts_enum.rs @@ -3,7 +3,7 @@ use std::mem; use swc_atoms::JsWord; use swc_common::{collections::AHashMap, Mark, DUMMY_SP}; use swc_ecma_ast::*; -use swc_ecma_utils::{undefined, ExprFactory}; +use swc_ecma_utils::{number::ToJsString, undefined, ExprFactory}; use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -207,14 +207,12 @@ impl<'a> EnumValueComputer<'a> { TsEnumRecordValue::String(format!("{}{}", left, right).into()) } (TsEnumRecordValue::Number(left), TsEnumRecordValue::String(right), op!(bin, "+")) => { - let mut buffer = ryu_js::Buffer::new(); - let left = buffer.format(left); + let left = left.to_js_string(); TsEnumRecordValue::String(format!("{}{}", left, right).into()) } (TsEnumRecordValue::String(left), TsEnumRecordValue::Number(right), op!(bin, "+")) => { - let mut buffer = ryu_js::Buffer::new(); - let right = buffer.format(right); + let right = right.to_js_string(); TsEnumRecordValue::String(format!("{}{}", left, right).into()) } @@ -279,7 +277,7 @@ impl<'a> EnumValueComputer<'a> { let expr = match expr { TsEnumRecordValue::String(s) => s.to_string(), - TsEnumRecordValue::Number(n) => ryu_js::Buffer::new().format(n).to_string(), + TsEnumRecordValue::Number(n) => n.to_js_string(), _ => return opaque_expr, };