Skip to content

Commit ce22557

Browse files
authored
feat(es/minifier): Compress foo ? num : 0 into num * !!foo (#9908)
**Related issue:** - Closes #9898
1 parent 60ae9f3 commit ce22557

File tree

46 files changed

+352
-303
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+352
-303
lines changed

crates/swc/tests/tsc-references/parserRealSource14.2.minified.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
167167
}, ctx = new AstPathContext();
168168
return TypeScript.getAstWalkerFactory().walk(script, function(cur, parent, walker) {
169169
if (isValidAstNode(cur)) {
170-
var inclusive = hasFlag(options, 1) || cur.nodeType === TypeScript.NodeType.Name || pos === script.limChar, minChar = cur.minChar, limChar = cur.limChar + (inclusive ? 1 : 0);
170+
var inclusive = hasFlag(options, 1) || cur.nodeType === TypeScript.NodeType.Name || pos === script.limChar, minChar = cur.minChar, limChar = cur.limChar + +!!inclusive;
171171
if (pos >= minChar && pos < limChar) {
172172
var previous = ctx.path.ast();
173173
(null == previous || cur.minChar >= previous.minChar && cur.limChar <= previous.limChar) && ctx.path.push(cur);

crates/swc/tests/vercel/full/d3-time-format/1/output/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ export default function v(e) {
187187
if (!e || "Z" in a || (a.Z = 0), "p" in a && (a.H = a.H % 12 + 12 * a.p), void 0 === a.m && (a.m = "q" in a ? a.q : 0), "V" in a) {
188188
if (a.V < 1 || a.V > 53) return null;
189189
"w" in a || (a.w = 1), "Z" in a ? (c = (o = (c = s(h(a.y, 0, 1))).getUTCDay()) > 4 || 0 === o ? f.ceil(c) : f(c), c = i.offset(c, (a.V - 1) * 7), a.y = c.getUTCFullYear(), a.m = c.getUTCMonth(), a.d = c.getUTCDate() + (a.w + 6) % 7) : (c = (o = (c = g(h(a.y, 0, 1))).getDay()) > 4 || 0 === o ? r.ceil(c) : r(c), c = t.offset(c, (a.V - 1) * 7), a.y = c.getFullYear(), a.m = c.getMonth(), a.d = c.getDate() + (a.w + 6) % 7);
190-
} else ("W" in a || "U" in a) && ("w" in a || (a.w = "u" in a ? a.u % 7 : "W" in a ? 1 : 0), o = "Z" in a ? s(h(a.y, 0, 1)).getUTCDay() : g(h(a.y, 0, 1)).getDay(), a.m = 0, a.d = "W" in a ? (a.w + 6) % 7 + 7 * a.W - (o + 5) % 7 : a.w + 7 * a.U - (o + 6) % 7);
190+
} else ("W" in a || "U" in a) && ("w" in a || (a.w = "u" in a ? a.u % 7 : +("W" in a)), o = "Z" in a ? s(h(a.y, 0, 1)).getUTCDay() : g(h(a.y, 0, 1)).getDay(), a.m = 0, a.d = "W" in a ? (a.w + 6) % 7 + 7 * a.W - (o + 5) % 7 : a.w + 7 * a.U - (o + 6) % 7);
191191
return "Z" in a ? (a.H += a.Z / 100 | 0, a.M += a.Z % 100, s(a)) : g(a);
192192
};
193193
}

crates/swc/tests/vercel/full/react-instantsearch/2/output/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ var f = function(e) {
2525
return e.props.indexId === t;
2626
}, h = function(e, t) {
2727
var r = p(e), a = p(t);
28-
return r && !a ? -1 : !r && a ? 1 : 0;
28+
return r && !a ? -1 : +(!r && !!a);
2929
};
3030
export default function S(u) {
3131
var o, l, S = u.indexName, v = u.initialState, x = u.searchClient, _ = u.resultsState, y = u.stalledSearchDelay, w = s(x, S, t({}, c));

crates/swc_ecma_minifier/src/compress/pure/conds.rs

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ impl Pure<'_> {
1515
/// - `!foo ? true : bar` => `!foo || bar`
1616
/// - `foo ? false : bar` => `!foo && bar`
1717
pub(super) fn compress_conds_as_logical(&mut self, e: &mut Expr) {
18-
let cond = match e {
19-
Expr::Cond(cond) => cond,
20-
_ => return,
21-
};
18+
if !self.options.conditionals {
19+
return;
20+
}
21+
22+
let Expr::Cond(cond) = e else { return };
2223

2324
let lt = cond.cons.get_type();
2425
if let Value::Known(Type::Bool) = lt {
@@ -100,10 +101,7 @@ impl Pure<'_> {
100101
return;
101102
}
102103

103-
let cond = match e {
104-
Expr::Cond(v) => v,
105-
_ => return,
106-
};
104+
let Expr::Cond(cond) = e else { return };
107105

108106
match (&mut *cond.cons, &mut *cond.alt) {
109107
(Expr::Bin(cons @ BinExpr { op: op!("||"), .. }), alt)
@@ -132,6 +130,58 @@ impl Pure<'_> {
132130
}
133131
}
134132

133+
///
134+
/// - `foo ? num : 0` => `num * !!foo`
135+
/// - `foo ? 0 : num` => `num * !foo`
136+
pub(super) fn compress_conds_as_arithmetic(&mut self, e: &mut Expr) {
137+
if !self.options.conditionals {
138+
return;
139+
}
140+
141+
let Expr::Cond(cond) = e else { return };
142+
let span = cond.span;
143+
144+
match (&mut *cond.cons, &mut *cond.alt) {
145+
(
146+
Expr::Lit(Lit::Num(Number { value, .. })),
147+
Expr::Lit(Lit::Num(Number { value: 0.0, .. })),
148+
) if *value > 0.0 => {
149+
report_change!("conditionals: `foo ? num : 0` => `num * !!foo`");
150+
self.changed = true;
151+
152+
let left = cond.cons.take();
153+
let mut right = cond.test.take();
154+
self.negate_twice(&mut right, false);
155+
156+
*e = Expr::Bin(BinExpr {
157+
span,
158+
op: op!("*"),
159+
left,
160+
right,
161+
})
162+
}
163+
(
164+
Expr::Lit(Lit::Num(Number { value: 0.0, .. })),
165+
Expr::Lit(Lit::Num(Number { value, .. })),
166+
) if *value > 0.0 => {
167+
report_change!("conditionals: `foo ? 0 : num` => `num * !foo`");
168+
self.changed = true;
169+
170+
let left = cond.alt.take();
171+
let mut right = cond.test.take();
172+
self.negate(&mut right, false, false);
173+
174+
*e = Expr::Bin(BinExpr {
175+
span,
176+
op: op!("*"),
177+
left,
178+
right,
179+
})
180+
}
181+
_ => (),
182+
}
183+
}
184+
135185
pub(super) fn negate_cond_expr(&mut self, cond: &mut CondExpr) {
136186
if negate_cost(&self.expr_ctx, &cond.test, true, false) >= 0 {
137187
return;

crates/swc_ecma_minifier/src/compress/pure/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,8 @@ impl VisitMut for Pure<'_> {
476476
debug_assert_valid(e);
477477
}
478478

479+
self.compress_conds_as_arithmetic(e);
480+
479481
self.lift_seqs_of_bin(e);
480482

481483
if e.is_seq() {

crates/swc_ecma_minifier/tests/benches-full/d3.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3841,10 +3841,10 @@ function(global, factory) {
38413841
];
38423842
}
38433843
_edgecode(x, y) {
3844-
return (x === this.xmin ? 0b0001 : x === this.xmax ? 0b0010 : 0b0000) | (y === this.ymin ? 0b0100 : y === this.ymax ? 0b1000 : 0b0000);
3844+
return (x === this.xmin ? 0b0001 : 0b0010 * (x === this.xmax)) | (y === this.ymin ? 0b0100 : 0b1000 * (y === this.ymax));
38453845
}
38463846
_regioncode(x, y) {
3847-
return (x < this.xmin ? 0b0001 : x > this.xmax ? 0b0010 : 0b0000) | (y < this.ymin ? 0b0100 : y > this.ymax ? 0b1000 : 0b0000);
3847+
return (x < this.xmin ? 0b0001 : 0b0010 * (x > this.xmax)) | (y < this.ymin ? 0b0100 : 0b1000 * (y > this.ymax));
38483848
}
38493849
}
38503850
const tau$3 = 2 * Math.PI, pow = Math.pow;
@@ -5192,7 +5192,7 @@ function(global, factory) {
51925192
else stream.point(to[0], to[1]);
51935193
}
51945194
function corner(p, direction) {
5195-
return 1e-6 > abs$2(p[0] - x0) ? direction > 0 ? 0 : 3 : 1e-6 > abs$2(p[0] - x1) ? direction > 0 ? 2 : 1 : 1e-6 > abs$2(p[1] - y0) ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
5195+
return 1e-6 > abs$2(p[0] - x0) ? 3 * !(direction > 0) : 1e-6 > abs$2(p[0] - x1) ? direction > 0 ? 2 : 1 : 1e-6 > abs$2(p[1] - y0) ? +(direction > 0) : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
51965196
}
51975197
function compareIntersection(a, b) {
51985198
return comparePoint(a.x, b.x);
@@ -7459,7 +7459,7 @@ function(global, factory) {
74597459
if (!Z || "Z" in d || (d.Z = 0), "p" in d && (d.H = d.H % 12 + 12 * d.p), void 0 === d.m && (d.m = "q" in d ? d.q : 0), "V" in d) {
74607460
if (d.V < 1 || d.V > 53) return null;
74617461
"w" in d || (d.w = 1), "Z" in d ? (week = (day$1 = (week = utcDate(newDate(d.y, 0, 1))).getUTCDay()) > 4 || 0 === day$1 ? utcMonday.ceil(week) : utcMonday(week), week = utcDay.offset(week, (d.V - 1) * 7), d.y = week.getUTCFullYear(), d.m = week.getUTCMonth(), d.d = week.getUTCDate() + (d.w + 6) % 7) : (week = (day$1 = (week = localDate(newDate(d.y, 0, 1))).getDay()) > 4 || 0 === day$1 ? monday.ceil(week) : monday(week), week = day.offset(week, (d.V - 1) * 7), d.y = week.getFullYear(), d.m = week.getMonth(), d.d = week.getDate() + (d.w + 6) % 7);
7462-
} else ("W" in d || "U" in d) && ("w" in d || (d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0), day$1 = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay(), d.m = 0, d.d = "W" in d ? (d.w + 6) % 7 + 7 * d.W - (day$1 + 5) % 7 : d.w + 7 * d.U - (day$1 + 6) % 7);
7462+
} else ("W" in d || "U" in d) && ("w" in d || (d.w = "u" in d ? d.u % 7 : +("W" in d)), day$1 = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay(), d.m = 0, d.d = "W" in d ? (d.w + 6) % 7 + 7 * d.W - (day$1 + 5) % 7 : d.w + 7 * d.U - (day$1 + 6) % 7);
74637463
return(// If a time zone is specified, all fields are interpreted as UTC and then
74647464
// offset according to the specified time zone.
74657465
"Z" in d ? (d.H += d.Z / 100 | 0, d.M += d.Z % 100, utcDate(d)) : localDate(d));

0 commit comments

Comments
 (0)