mirror of
https://github.com/swc-project/swc.git
synced 2024-11-23 09:38:16 +03:00
feat(es/utils): Support for arrays using cast_to_number
(#9212)
**Description:** This PR allows `ArrayLit`s to be converted to numbers in the `cast_to_number` function. This allows expressions using arrays to be converted to numbers. See some example expressions below that were previously not able to be computed, but are now able to due to this change. ```js +[] // 0 +[[]] // 0 +[1] // 1 +[undefined] // 0 +[null] // 0 +[[1]] // 1 +[,] // 0 +[,,] // NaN ``` Regarding the implementation, arrays are converted to strings, and the string is then parsed as a number. So arrays like `[]` and `[undefined]` return `""` which then return `0` when parsed as a string. This is also why arrays with more than one element can't be parsed because e.g. `[1, 2]` returns `"1,2"`. This procedure follows the ECMAScript specification. https://262.ecma-international.org/6.0/#sec-tonumber https://262.ecma-international.org/6.0/#sec-toprimitive
This commit is contained in:
parent
b4dbe0be06
commit
2aef14d34d
@ -488,6 +488,27 @@ fn test_unary_ops_4() {
|
||||
fold("a=~~0xffffffff", "a=-1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unary_ops_5() {
|
||||
// Empty arrays
|
||||
fold("+[]", "0");
|
||||
fold("+[[]]", "0");
|
||||
fold("+[[[]]]", "0");
|
||||
|
||||
// Arrays with one element
|
||||
fold("+[1]", "1");
|
||||
fold("+[[1]]", "1");
|
||||
fold("+[undefined]", "0");
|
||||
fold("+[null]", "0");
|
||||
fold("+[,]", "0");
|
||||
|
||||
// Arrays with more than one element
|
||||
fold("+[1, 2]", "NaN");
|
||||
fold("+[[1], 2]", "NaN");
|
||||
fold("+[,1]", "NaN");
|
||||
fold("+[,,]", "NaN");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unary_ops_string_compare() {
|
||||
fold_same("a = -1");
|
||||
|
@ -890,6 +890,13 @@ pub trait ExprExt {
|
||||
Lit::Str(Str { value, .. }) => return (Pure, num_from_str(value)),
|
||||
_ => return (Pure, Unknown),
|
||||
},
|
||||
Expr::Array(..) => {
|
||||
let Known(s) = self.as_pure_string(ctx) else {
|
||||
return (Pure, Unknown);
|
||||
};
|
||||
|
||||
return (Pure, num_from_str(&s));
|
||||
}
|
||||
Expr::Ident(Ident { sym, span, .. }) => match &**sym {
|
||||
"undefined" | "NaN" if span.ctxt == ctx.unresolved_ctxt => f64::NAN,
|
||||
"Infinity" if span.ctxt == ctx.unresolved_ctxt => f64::INFINITY,
|
||||
@ -1572,7 +1579,6 @@ pub fn num_from_str(s: &str) -> Value<f64> {
|
||||
return Unknown;
|
||||
}
|
||||
|
||||
// TODO: Check if this is correct
|
||||
let s = s.trim();
|
||||
|
||||
if s.is_empty() {
|
||||
|
Loading…
Reference in New Issue
Block a user