Skip to content

Commit 2aef14d

Browse files
authoredJul 12, 2024··
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
1 parent b4dbe0b commit 2aef14d

File tree

2 files changed

+28
-1
lines changed
  • crates
    • swc_ecma_transforms_optimization/src/simplify/expr
    • swc_ecma_utils/src

2 files changed

+28
-1
lines changed
 

‎crates/swc_ecma_transforms_optimization/src/simplify/expr/tests.rs

+21
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,27 @@ fn test_unary_ops_4() {
488488
fold("a=~~0xffffffff", "a=-1");
489489
}
490490

491+
#[test]
492+
fn test_unary_ops_5() {
493+
// Empty arrays
494+
fold("+[]", "0");
495+
fold("+[[]]", "0");
496+
fold("+[[[]]]", "0");
497+
498+
// Arrays with one element
499+
fold("+[1]", "1");
500+
fold("+[[1]]", "1");
501+
fold("+[undefined]", "0");
502+
fold("+[null]", "0");
503+
fold("+[,]", "0");
504+
505+
// Arrays with more than one element
506+
fold("+[1, 2]", "NaN");
507+
fold("+[[1], 2]", "NaN");
508+
fold("+[,1]", "NaN");
509+
fold("+[,,]", "NaN");
510+
}
511+
491512
#[test]
492513
fn test_unary_ops_string_compare() {
493514
fold_same("a = -1");

‎crates/swc_ecma_utils/src/lib.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,13 @@ pub trait ExprExt {
890890
Lit::Str(Str { value, .. }) => return (Pure, num_from_str(value)),
891891
_ => return (Pure, Unknown),
892892
},
893+
Expr::Array(..) => {
894+
let Known(s) = self.as_pure_string(ctx) else {
895+
return (Pure, Unknown);
896+
};
897+
898+
return (Pure, num_from_str(&s));
899+
}
893900
Expr::Ident(Ident { sym, span, .. }) => match &**sym {
894901
"undefined" | "NaN" if span.ctxt == ctx.unresolved_ctxt => f64::NAN,
895902
"Infinity" if span.ctxt == ctx.unresolved_ctxt => f64::INFINITY,
@@ -1572,7 +1579,6 @@ pub fn num_from_str(s: &str) -> Value<f64> {
15721579
return Unknown;
15731580
}
15741581

1575-
// TODO: Check if this is correct
15761582
let s = s.trim();
15771583

15781584
if s.is_empty() {

0 commit comments

Comments
 (0)
Please sign in to comment.