mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(minifier): minimize Number constructor (#8245)
This commit is contained in:
parent
2f52f333fa
commit
fd5af73a22
1 changed files with 57 additions and 0 deletions
|
|
@ -35,6 +35,7 @@ impl<'a> Traverse<'a> for PeepholeFoldConstants {
|
|||
Expression::StaticMemberExpression(e) => Self::try_fold_static_member_expr(e, ctx),
|
||||
Expression::LogicalExpression(e) => Self::try_fold_logical_expr(e, ctx),
|
||||
Expression::ChainExpression(e) => Self::try_fold_optional_chain(e, ctx),
|
||||
Expression::CallExpression(e) => Self::try_fold_number_constructor(e, ctx),
|
||||
_ => None,
|
||||
} {
|
||||
*expr = folded_expr;
|
||||
|
|
@ -555,6 +556,51 @@ impl<'a, 'b> PeepholeFoldConstants {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn try_fold_number_constructor(
|
||||
e: &CallExpression<'a>,
|
||||
ctx: Ctx<'a, 'b>,
|
||||
) -> Option<Expression<'a>> {
|
||||
let Expression::Identifier(ident) = &e.callee else { return None };
|
||||
if ident.name != "Number" {
|
||||
return None;
|
||||
}
|
||||
if !ctx.is_global_reference(ident) {
|
||||
return None;
|
||||
}
|
||||
if e.arguments.len() != 1 {
|
||||
return None;
|
||||
}
|
||||
Some(ctx.value_to_expr(
|
||||
e.span,
|
||||
ConstantValue::Number(match &e.arguments[0] {
|
||||
// `Number(undefined)` -> `NaN`
|
||||
Argument::Identifier(ident) if ctx.is_identifier_undefined(ident) => f64::NAN,
|
||||
// `Number(null)` -> `0`
|
||||
Argument::NullLiteral(_) => 0.0,
|
||||
// `Number(true)` -> `1` `Number(false)` -> `0`
|
||||
Argument::BooleanLiteral(b) => f64::from(b.value),
|
||||
// `Number(100)` -> `100`
|
||||
Argument::NumericLiteral(n) => n.value,
|
||||
// `Number("a")` -> `+"a"` -> `NaN`
|
||||
// `Number("1")` -> `+"1"` -> `1`
|
||||
Argument::StringLiteral(n) => {
|
||||
let argument =
|
||||
ctx.ast.expression_string_literal(n.span, n.value.clone(), n.raw.clone());
|
||||
if let Some(n) = ctx.eval_to_number(&argument) {
|
||||
n
|
||||
} else {
|
||||
return Some(ctx.ast.expression_unary(
|
||||
e.span,
|
||||
UnaryOperator::UnaryPlus,
|
||||
argument,
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
}),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeFoldConstantsTest.java>
|
||||
|
|
@ -1676,4 +1722,15 @@ mod test {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_number_constructor() {
|
||||
test("Number(undefined)", "NaN");
|
||||
test("Number(null)", "0");
|
||||
test("Number(true)", "1");
|
||||
test("Number(false)", "0");
|
||||
test("Number('a')", "NaN");
|
||||
test("Number('1')", "1");
|
||||
test_same("var Number; Number(1)");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue