Skip to content

Commit

Permalink
fix(es/minifier): Improve DCE (#9853)
Browse files Browse the repository at this point in the history
**Description:**

 - We should check for the superclass while dropping class declarations.
 - Add early-check for `null && foo` and `true || foo`.


**Related issue:**

 - Closes #9823
  • Loading branch information
kdy1 authored Jan 8, 2025
1 parent caa7f37 commit 85fb16c
Show file tree
Hide file tree
Showing 17 changed files with 114 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
//// [accessorsOverrideProperty3.ts]
Animal;
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
//// [accessorsOverrideProperty4.ts]
Animal;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//// [asyncGeneratorParameterEvaluation.ts]
import "@swc/helpers/_/_extends";
import "@swc/helpers/_/_object_destructuring_empty";
import "@swc/helpers/_/_wrap_async_generator";
import { _ as _extends } from "@swc/helpers/_/_extends";
import { _ as _object_destructuring_empty } from "@swc/helpers/_/_object_destructuring_empty";
import { _ as _wrap_async_generator } from "@swc/helpers/_/_wrap_async_generator";
Super;
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//// [asyncGeneratorParameterEvaluation.ts]
import "@swc/helpers/_/_extends";
import "@swc/helpers/_/_object_destructuring_empty";
import { _ as _extends } from "@swc/helpers/_/_extends";
import { _ as _object_destructuring_empty } from "@swc/helpers/_/_object_destructuring_empty";
Super;
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
//// [asyncGeneratorParameterEvaluation.ts]
Super;
6 changes: 6 additions & 0 deletions crates/swc/tests/tsc-references/override19.2.minified.js
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
//// [override19.ts]
class Context {
}
class A {
doSomething() {}
}
CreateMixin(Context, A), CreateMixin(Context, A);
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
//// [overrideInterfaceProperty.ts]
Mup, Mup;
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
//// [foo.ts]
//// [bar.js]
Foo;
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,13 @@ function copyBytes(src, dst, off = 0) {
return src.byteLength;
}
const DEFAULT_BUF_SIZE = 4096;
class PartialReadError extends Deno.errors.UnexpectedEof {
name = "PartialReadError";
partial;
constructor(){
super("Encountered UnexpectedEof, data only partially read");
}
}
class AbstractBufBase {
buf;
usedBufferBytes = 0;
Expand Down
7 changes: 7 additions & 0 deletions crates/swc_bundler/tests/fixture/deno-9591/output/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1837,6 +1837,13 @@ function copyBytes(src, dst, off = 0) {
return src.byteLength;
}
const DEFAULT_BUF_SIZE = 4096;
class PartialReadError extends Deno.errors.UnexpectedEof {
name = "PartialReadError";
partial;
constructor(){
super("Encountered UnexpectedEof, data only partially read");
}
}
class AbstractBufBase {
buf;
usedBufferBytes = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
(() => {
"use strict";
class Element { }
class PointElement extends Element {
static id = 'point';
constructor(cfg) {
super();
}
}

// var chart_elements = /*#__PURE__*/ Object.freeze({
// PointElement: PointElement
// });

var chart_elements = /*#__PURE__*/(null && (Object.freeze({
PointElement: PointElement
})));

const registerables = null && ([
chart_elements,
chart_plugins,
]);

console.log('Done 1')
})()
;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Done 1');
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(() => {
"use strict";
class Element { }


// var chart_elements = /*#__PURE__*/ Object.freeze({
// PointElement: PointElement
// });

var chart_elements = /*#__PURE__*/(null && (Object.freeze({
Element: Element
})));

const registerables = null && ([
chart_elements,
chart_plugins
]);

console.log('Done 2')
})()
;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Done 2');
7 changes: 7 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/9823/3/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(function () {
function foo() {

}

console.log('Done')
})()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Done');
26 changes: 25 additions & 1 deletion crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use swc_ecma_transforms_base::{
perf::{cpu_count, ParVisitMut, Parallel},
};
use swc_ecma_utils::{
collect_decls, find_pat_ids, ExprCtx, ExprExt, IsEmpty, ModuleItemLike, StmtLike,
collect_decls, find_pat_ids, ExprCtx, ExprExt, IsEmpty, ModuleItemLike, StmtLike, Value::Known,
};
use swc_ecma_visit::{
noop_visit_mut_type, noop_visit_type, visit_mut_pass, Visit, VisitMut, VisitMutWith, VisitWith,
Expand Down Expand Up @@ -655,6 +655,24 @@ impl TreeShaker {
.map(|v| v.usage == 0)
.unwrap_or_default()
}

/// Drops RHS from `null && foo`
fn optimize_bin_expr(&mut self, n: &mut Expr) {
let Expr::Bin(b) = n else {
return;
};

if b.op == op!("&&") && b.left.as_pure_bool(&self.expr_ctx) == Known(false) {
*n = *b.left.take();
self.changed = true;
return;
}

if b.op == op!("||") && b.left.as_pure_bool(&self.expr_ctx) == Known(true) {
*n = *b.left.take();
self.changed = true;
}
}
}

impl VisitMut for TreeShaker {
Expand Down Expand Up @@ -697,6 +715,10 @@ impl VisitMut for TreeShaker {
}
Decl::Class(c) => {
if self.can_drop_binding(c.ident.to_id(), false)
&& c.class
.super_class
.as_deref()
.map_or(true, |e| !e.may_have_side_effects(&self.expr_ctx))
&& c.class.body.iter().all(|m| match m {
ClassMember::Method(m) => !matches!(m.key, PropName::Computed(..)),
ClassMember::ClassProp(m) => {
Expand Down Expand Up @@ -757,6 +779,8 @@ impl VisitMut for TreeShaker {
fn visit_mut_expr(&mut self, n: &mut Expr) {
n.visit_mut_children_with(self);

self.optimize_bin_expr(n);

if let Expr::Call(CallExpr {
callee: Callee::Expr(callee),
args,
Expand Down

0 comments on commit 85fb16c

Please sign in to comment.