mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(codegen): don't emit space between postfix -- and > when minifying (#23036)
## What `a-- > b` was minified as `a-- >b` (a space before `>`) to avoid producing the `-->` token sequence. But `-->` is only an HTML close comment (`SingleLineHTMLCloseComment`) at the **start of a line**, and a postfix `--` always has an operand before it — so `a-->b` is never a comment and always parses as `(a--) > b`. | Input | Before | After | | --- | --- | --- | | `while (i-- > 0) f()` | `while(i-- >0)f()` | `while(i-->0)f()` | | `x = a-- > b` | `x=a-- >b` | `x=a-->b` | Verified in node (`while(i-->0)` yields `[2,1,0]`). This goes one step beyond esbuild, which keeps the conservative space. The `< ! --` guard (avoiding `<!--`, which *can* appear mid-line) is left untouched.
This commit is contained in:
3 files changed
+7
-6
No files matched your search
@@ -826,22 +826,21 @@ impl<'a> Codegen<'a> {
|
||||
// "x + + y" => "x+ +y"
|
||||
// "x ++ + y" => "x+++y"
|
||||
// "x + ++ y" => "x+ ++y"
|
||||
// "-- >" => "-- >"
|
||||
// "< ! --" => "<! --"
|
||||
// Note: `a-- > b` does not need a space (`a-->b` is `(a--) > b`); `-->` is
|
||||
// only an HTML close comment at the start of a line, and a postfix `--`
|
||||
// always has an operand before it.
|
||||
let bin_op_add = Operator::Binary(BinaryOperator::Addition);
|
||||
let bin_op_sub = Operator::Binary(BinaryOperator::Subtraction);
|
||||
let un_op_pos = Operator::Unary(UnaryOperator::UnaryPlus);
|
||||
let un_op_pre_inc = Operator::Update(UpdateOperator::Increment);
|
||||
let un_op_neg = Operator::Unary(UnaryOperator::UnaryNegation);
|
||||
let un_op_pre_dec = Operator::Update(UpdateOperator::Decrement);
|
||||
let un_op_post_dec = Operator::Update(UpdateOperator::Decrement);
|
||||
let bin_op_gt = Operator::Binary(BinaryOperator::GreaterThan);
|
||||
let un_op_not = Operator::Unary(UnaryOperator::LogicalNot);
|
||||
if ((prev == bin_op_add || prev == un_op_pos)
|
||||
&& (next == bin_op_add || next == un_op_pos || next == un_op_pre_inc))
|
||||
|| ((prev == bin_op_sub || prev == un_op_neg)
|
||||
&& (next == bin_op_sub || next == un_op_neg || next == un_op_pre_dec))
|
||||
|| (prev == un_op_post_dec && next == bin_op_gt)
|
||||
|| (prev == un_op_not
|
||||
&& next == un_op_pre_dec
|
||||
// `prev == UnaryOperator::LogicalNot` which means last byte is ASCII,
|
||||
|
||||
@@ -799,7 +799,9 @@ fn test_whitespace() {
|
||||
test_minify("x + y--", "x+y--;");
|
||||
test_minify("x - y--", "x-y--;");
|
||||
|
||||
test_minify("x-- > y", "x-- >y;");
|
||||
// `-->` is only an HTML close comment at the start of a line, and `x--` always
|
||||
// has an operand before it, so no space is needed.
|
||||
test_minify("x-- > y", "x-->y;");
|
||||
test_minify("x < !--y", "x<! --y;");
|
||||
test_minify("x > !--y", "x>!--y;");
|
||||
test_minify("!--y", "!--y;");
|
||||
|
||||
@@ -23,5 +23,5 @@ Original | minified | minified | gzip | gzip | Iterations | Fi
|
||||
|
||||
6.69 MB | 2.22 MB | 2.31 MB | 458.45 kB | 488.28 kB | 4 | antd.js
|
||||
|
||||
10.95 MB | 3.33 MB | 3.49 MB | 853.33 kB | 915.50 kB | 4 | typescript.js
|
||||
10.95 MB | 3.33 MB | 3.49 MB | 853.35 kB | 915.50 kB | 4 | typescript.js
|
||||
|
||||
Reference in new issue
Block a user