Skip to content

Commit

Permalink
fix(minifier): rotate associative operators to make it more idempotent
Browse files Browse the repository at this point in the history
  • Loading branch information
camc314 committed Jan 10, 2025
1 parent 31a7588 commit 53deb45
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax {
Self::try_compress_assignment_to_update_expression(e, ctx)
}
Expression::LogicalExpression(e) => Self::try_compress_is_null_or_undefined(e, ctx)
.or_else(|| self.try_compress_logical_expression_to_assignment_expression(e, ctx)),
.or_else(|| self.try_compress_logical_expression_to_assignment_expression(e, ctx))
.or_else(|| Self::try_rotate_logical_expression(e, ctx)),
Expression::TemplateLiteral(t) => Self::try_fold_template_literal(t, ctx),
Expression::BinaryExpression(e) => Self::try_fold_loose_equals_undefined(e, ctx)
.or_else(|| Self::try_compress_typeof_undefined(e, ctx)),
Expand Down Expand Up @@ -503,6 +504,29 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
Some(ctx.ast.move_expression(&mut expr.right))
}

/// `a || (b || c);` -> `(a || b) || c;`
fn try_rotate_logical_expression(
expr: &mut LogicalExpression<'a>,
ctx: Ctx<'a, 'b>,
) -> Option<Expression<'a>> {
let Expression::LogicalExpression(right) = &mut expr.right else { return None };
if right.operator != expr.operator {
return None;
}
let new_expr = ctx.ast.expression_logical(
expr.span,
ctx.ast.expression_logical(
expr.span,
ctx.ast.move_expression(&mut expr.left),
expr.operator,
ctx.ast.move_expression(&mut right.left),
),
expr.operator,
ctx.ast.move_expression(&mut right.right),
);
Some(new_expr)
}

/// Returns `true` if the assignment target and expression have no side effect for *evaluation* and points to the same reference.
///
/// Evaluation here means `Evaluation` in the spec.
Expand Down
9 changes: 9 additions & 0 deletions crates/oxc_minifier/tests/ast_passes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ fn integration() {
return console.log(e || JSON.stringify(os));
});"#,
);

test_idempotent(
"if (!(foo instanceof Var) || open) {
arg0 = null;
} else if (que || !(foo && bar)) {
if (baz()) arg0 = null;
}",
"(!(foo instanceof Var) || open || (que || !(foo && bar)) && baz()) && (arg0 = null);",
);
}

#[test] // https://github.com/oxc-project/oxc/issues/4341
Expand Down

0 comments on commit 53deb45

Please sign in to comment.