fix(es/minifier): keep directive prologue when merging if returns

Merged
KD
12d ago
+147-2

The if_return pass merged the directive prologue of a function body into a sequence expression. A directive such as "use strict" then became a discarded void operand and stopped being a directive. The function lost strict mode. For example, this in a strict function became the global object, and arguments aliased its parameters.

This change keeps the leading string-literal statements of a function body out of the if_return merge. The pass still merges the statements after them. This applies to ordinary functions and to block-bodied arrow functions.

Tests:

  • Add the fixtures issues/9238, issues/9238-arrow and issues/9238-prologue. They check arguments aliasing, this in a strict function, a returned function in a strict arrow, multiple directives, and safe merging of ordinary statements. Each fixture also has a expected.repeat-stdout check for two minification rounds. All new fixtures fail without the fix.
  • Update the next/swc-4559 snapshot. It now keeps "use strict", which the old output wrongly dropped.
  • Update the antd gzipped size in libs-size.snapshot.md (+0.01 KiB) for the same reason.

Local validation (on the final revision): cargo fmt --all, cargo clippy --all --all-targets -- -D warnings, cargo test -p swc_ecma_minifier and crates/swc_ecma_minifier/scripts/exec.sh passed. CI was not run locally.

Closes #9238