Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion crates/swc/tests/tsc-references/constEnum2.1.normal.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
var CONST = 9000 % 2;
var D = function(D) {
D[D["e"] = 199 * Math.floor(Math.random() * 1000)] = "e";
D[D["f"] = 10 - 100 * Math.floor(Math.random() % 8)] = "f";
D[D["f"] = D.d - 100 * Math.floor(Math.random() % 8)] = "f";
D[D["g"] = CONST] = "g";
return D;
}(D || {});
2 changes: 1 addition & 1 deletion crates/swc/tests/tsc-references/constEnum2.2.minified.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
//// [constEnum2.ts]
var D, D1 = ((D = D1 || {})[D.e = 199 * Math.floor(1000 * Math.random())] = "e", D[D.f = 10 - 100 * Math.floor(Math.random() % 8)] = "f", D[D.g = 0] = "g", D);
var D, D1 = ((D = D1 || {})[D.e = 199 * Math.floor(1000 * Math.random())] = "e", D[D.f = D.d - 100 * Math.floor(Math.random() % 8)] = "f", D[D.g = 0] = "g", D);
2 changes: 1 addition & 1 deletion crates/swc/tests/tsc-references/enumBasics.1.normal.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var E2 = /*#__PURE__*/ function(E2) {
var E3 = function(E3) {
E3[E3["X"] = 'foo'.length] = "X";
E3[E3["Y"] = 7] = "Y";
E3[E3["Z"] = +"foo"] = "Z";
E3[E3["Z"] = +'foo'] = "Z";
return E3;
}(E3 || {});
// Enum with constant members followed by computed members
Expand Down
13 changes: 11 additions & 2 deletions crates/swc_ecma_transforms_typescript/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
retain::{should_retain_module_item, should_retain_stmt},
semantic::SemanticInfo,
shared::enum_member_id_atom,
ts_enum::{TsEnumRecordKey, TsEnumRecordValue},
ts_enum::{EnumValueComputer, TsEnumRecordKey, TsEnumRecordValue},
utils::{assign_value_to_this_private_prop, assign_value_to_this_prop, Factory},
};

Expand Down Expand Up @@ -1063,7 +1063,16 @@ impl Transform {
member_name: name.clone(),
};

let value = self.semantic.enum_record.get(&key).unwrap().clone();
let mut value = self.semantic.enum_record.get(&key).unwrap().clone();

if let TsEnumRecordValue::Opaque(expr) = &mut value {
*expr = m.init.unwrap();
expr.visit_mut_with(&mut EnumValueComputer {
enum_id: &id.to_id(),
unresolved_ctxt: self.unresolved_ctxt,
record: &self.semantic.enum_record,
});
Comment on lines +1088 to +1095
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EnumMemberRefQuery { enum_id: &id.to_id(), .. } also borrows a temporary Id. After introducing a local enum_id: Id (e.g. let enum_id = id.to_id();), pass enum_id: &enum_id here as well to avoid borrowing a temporary and to ensure the reference outlives the rewriter.

Copilot uses AI. Check for mistakes.
}

EnumMemberItem { span, name, value }
})
Expand Down
14 changes: 9 additions & 5 deletions crates/swc_ecma_transforms_typescript/src/ts_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,7 @@ pub(crate) struct EnumValueComputer<'a> {
/// https://github.com/microsoft/TypeScript/pull/50528
impl EnumValueComputer<'_> {
pub fn compute(&mut self, expr: Box<Expr>) -> TsEnumRecordValue {
let mut expr = self.compute_rec(expr);
if let TsEnumRecordValue::Opaque(expr) = &mut expr {
expr.visit_mut_with(self);
}
expr
self.compute_rec(expr)
}

fn compute_rec(&self, expr: Box<Expr>) -> TsEnumRecordValue {
Expand Down Expand Up @@ -155,6 +151,14 @@ impl EnumValueComputer<'_> {
Expr::Bin(e) => self.compute_bin(e),
Expr::Member(e) => self.compute_member(e),
Expr::Tpl(e) => self.compute_tpl(e),
// Handle TypeScript type expressions by stripping them
// and computing the inner expression
Expr::TsAs(TsAsExpr { expr, .. })
| Expr::TsNonNull(TsNonNullExpr { expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { expr, .. })
| Expr::TsInstantiation(TsInstantiation { expr, .. })
| Expr::TsSatisfies(TsSatisfiesExpr { expr, .. }) => self.compute_rec(expr),
_ => TsEnumRecordValue::Opaque(expr),
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var A = function(A) {
A[A["a"] = a] = "a";
A[A["a"] = A.a] = "a";
return A;
}(A || {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var Foo = function(Foo) {
Foo[Foo["a"] = (class {
constructor(b){
this.b = b;
}
}, 0)] = "a";
return Foo;
}(Foo || {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var Foo = function(Foo) {
Foo[Foo["a"] = (()=>{
let Bar = /*#__PURE__*/ function(Bar) {
Bar["a"] = "a";
Bar["b"] = "b";
return Bar;
}({});
return 0;
})()] = "a";
return Foo;
}(Foo || {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var Foo = function(Foo) {
Foo[Foo["a"] = foo('x')] = "a";
return Foo;
}(Foo || {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var RefType = /*#__PURE__*/ function(RefType) {
RefType["property"] = "11";
RefType["event"] = "22";
return RefType;
}(RefType || {});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var x = 10;
var Foo = function(Foo) {
Foo[Foo["a"] = 10] = "a";
Foo[Foo["b"] = 10] = "b";
Foo[Foo["c"] = 10 + x] = "c";
Foo[Foo["c"] = Foo.b + x] = "c";
Foo[Foo["d"] = Foo.c] = "d";
return Foo;
}(Foo || {});
Expand Down
37 changes: 37 additions & 0 deletions crates/swc_ecma_transforms_typescript/tests/strip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,43 @@ to!(
}"
);

to!(
ts_enum_with_type_assertion,
"enum RefType {
property = '11' as any,
event = '22' as any,
}"
);

to!(
ts_enum_with_opaque_expr,
"enum Foo {
a = foo('x' as any),
}"
);

to!(
ts_enum_with_nested_class,
"enum Foo {
a = (class {
constructor(public b: string) { }
}, 0)
}"
);

to!(
ts_enum_with_nested_enum,
"enum Foo {
a = (() => {
enum Bar {
a = 'a',
b = 'b',
}
return 0;
})(),
}"
);

to!(module_01, "module 'foo'{ }");

to!(declare_01, "declare var env: FOO");
Expand Down
Loading