feat(minifier): fold void 1 -> void 0 (#5670)

This commit is contained in:
Boshen 2024-09-10 08:11:09 +00:00
parent 2da42efb6f
commit 68c3cf544f
3 changed files with 22 additions and 3 deletions

View file

@ -108,10 +108,16 @@ impl<'a> AstBuilder<'a> {
/* ---------- Constructors ---------- */
/// `0`
#[inline]
pub fn number_0(self) -> Expression<'a> {
self.expression_numeric_literal(Span::default(), 0.0, "0", NumberBase::Decimal)
}
/// `void 0`
#[inline]
pub fn void_0(self) -> Expression<'a> {
let num = self.expression_numeric_literal(Span::default(), 0.0, "0", NumberBase::Decimal);
let num = self.number_0();
Expression::UnaryExpression(self.alloc(self.unary_expression(
Span::default(),
UnaryOperator::Void,

View file

@ -2,7 +2,7 @@
//!
//! <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PeepholeFoldConstants.java>
use std::cmp::Ordering;
use std::{cmp::Ordering, mem};
use num_bigint::BigInt;
use oxc_ast::{ast::*, AstBuilder, Visit};
@ -166,6 +166,7 @@ impl<'a> FoldConstants<'a> {
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
match expr.operator {
UnaryOperator::Void => Self::try_reduce_void(expr, ctx),
UnaryOperator::Typeof => self.try_fold_type_of(expr, ctx),
UnaryOperator::LogicalNot => {
expr.argument.to_boolean().map(|b| self.ast.expression_boolean_literal(SPAN, !b))
@ -182,6 +183,19 @@ impl<'a> FoldConstants<'a> {
}
}
/// `void 1` -> `void 0`
fn try_reduce_void(
expr: &mut UnaryExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
if (!expr.argument.is_number() || !expr.argument.is_number_0())
&& !expr.may_have_side_effects()
{
let _ = mem::replace(&mut expr.argument, ctx.ast.number_0());
}
None
}
/// Folds 'typeof(foo)' if foo is a literal, e.g.
/// `typeof("bar") --> "string"`
/// `typeof(6) --> "number"`

View file

@ -626,7 +626,6 @@ fn test_fold_logical_op2() {
}
#[test]
#[ignore]
fn test_fold_void() {
test_same("void 0");
test("void 1", "void 0");