Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/breezy-experts-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
swc_ecma_utils: patch
swc_core: patch
swc_ecma_lexer: patch
swc_ecma_parser: patch
swc_ecma_usage_analyzer: patch
---

fix(es/minifier): Fix cycle detection
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
//// [privateNamesConstructorChain-1.ts]
import "@swc/helpers/_/_class_private_field_get";
import "@swc/helpers/_/_class_private_field_init";
import "@swc/helpers/_/_class_private_field_set";
import "@swc/helpers/_/_class_static_private_field_spec_get";
import { _ as _class_private_field_get } from "@swc/helpers/_/_class_private_field_get";
import { _ as _class_private_field_init } from "@swc/helpers/_/_class_private_field_init";
import { _ as _class_private_field_set } from "@swc/helpers/_/_class_private_field_set";
import { _ as _class_static_private_field_spec_get } from "@swc/helpers/_/_class_static_private_field_spec_get";
var _foo = /*#__PURE__*/ new WeakMap();
class Parent {
accessChildProps() {
_class_private_field_get(new Child(), _foo), _class_static_private_field_spec_get(Child, Parent, _bar);
}
constructor(){
_class_private_field_init(this, _foo, {
writable: !0,
value: void 0
}), _class_private_field_set(this, _foo, 3);
}
}
var _bar = {
writable: !0,
value: 5
}, _foo1 = /*#__PURE__*/ new WeakMap(), _bar1 = /*#__PURE__*/ new WeakMap();
class Child extends Parent {
constructor(...args){
super(...args), _class_private_field_init(this, _foo1, {
writable: !0,
value: void 0
}), _class_private_field_init(this, _bar1, {
writable: !0,
value: void 0
}), _class_private_field_set(this, _foo1, "foo"), _class_private_field_set(this, _bar1, "bar");
}
}
26 changes: 26 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/cycle-1/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
(() => {
class A {
cycle() {
return B;
}
}
class B {
cycle() {
return A
}
}

class ExtendsA1 extends sideEffectWith(A) {}
class Unused1 {
constructor() {
ExtendsA1
}
}
class ExtendsA2 extends sideEffectWith(A) {}
class Unused2 {
async put() {
ExtendsA2
}
}
})();

11 changes: 11 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/cycle-1/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class A {
cycle() {
return B;
}
}
class B {
cycle() {
return A;
}
}
sideEffectWith(A), sideEffectWith(A);
20 changes: 20 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/cycle-2/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

(() => {
class C {
cycle() {
return D;
}
}
class D {
cycle() {
return C
}
}

class ExtendsC extends sideEffectWith(C) {}
class Unused {
constructor() {
ExtendsC
}
}
})();
11 changes: 11 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/cycle-2/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class C {
cycle() {
return D;
}
}
class D {
cycle() {
return C;
}
}
sideEffectWith(C);
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,16 @@ impl Visit for Analyzer<'_> {
}

fn visit_class_decl(&mut self, n: &ClassDecl) {
if let Some(super_class) = &n.class.super_class {
super_class.visit_with(self);
}

self.with_ast_path(vec![n.ident.to_id()], |v| {
let old = v.cur_class_id.take();
v.cur_class_id = Some(n.ident.to_id());
n.visit_children_with(v);
n.ident.visit_with(v);
n.class.decorators.visit_with(v);
n.class.body.visit_with(v);
v.cur_class_id = old;

if !n.class.decorators.is_empty() {
Expand Down
Loading