mirror of
https://github.com/swc-project/swc.git
synced 2024-11-29 03:32:32 +03:00
fix(es/minifier): Fix evaluation of -0
as a string (#9011)
**Related issue:** - Closes #9010 --------- Co-authored-by: magic-akari <akari.ccino@gmail.com>
This commit is contained in:
parent
1f911f9d19
commit
9f8e24a76c
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -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-js",
|
||||
"stacker",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -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,
|
||||
|
@ -11316,3 +11316,12 @@ fn issue_8982_2() {
|
||||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_9010() {
|
||||
run_default_exec_test(
|
||||
r#"
|
||||
console.log(-0 + [])
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@ num_cpus = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
rayon = { workspace = true, optional = true }
|
||||
rustc-hash = { workspace = true }
|
||||
ryu-js = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
unicode-id = { workspace = true }
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -979,7 +981,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(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")),
|
||||
Lit::Null(..) => Known(Cow::Borrowed("null")),
|
||||
|
11
crates/swc_ecma_utils/src/number.rs
Normal file
11
crates/swc_ecma_utils/src/number.rs
Normal file
@ -0,0 +1,11 @@
|
||||
/// <https://tc39.es/ecma262/#sec-numeric-types-number-tostring>
|
||||
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()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user