diff --git a/packages/angular/build/src/tools/babel/plugins/adjust-typescript-enums_oxc_spec.ts b/packages/angular/build/src/tools/babel/plugins/adjust-typescript-enums_oxc_spec.ts index fc01eecf991a..82877cb3b2e3 100644 --- a/packages/angular/build/src/tools/babel/plugins/adjust-typescript-enums_oxc_spec.ts +++ b/packages/angular/build/src/tools/babel/plugins/adjust-typescript-enums_oxc_spec.ts @@ -280,4 +280,103 @@ describe('adjust-typescript-enums oxc-transform implementation', () => { `, }), ); + + it( + 'handles TypeScript enums with chained exports assignment (angular-split / shared-docs pattern)', + testCase({ + input: ` + var Area; + (function (a1) { + a1[a1["areaAfter"] = 0] = "areaAfter"; + a1[a1["preserveOtherCategoryOrder"] = 1] = "preserveOtherCategoryOrder"; + })(Area || (Area = exports.Area = {})); + `, + expected: ` + var Area = /*#__PURE__*/ (function (a1) { + a1[(a1["areaAfter"] = 0)] = "areaAfter"; + a1[(a1["preserveOtherCategoryOrder"] = 1)] = "preserveOtherCategoryOrder"; + return a1; + })(Area || (exports.Area = {})); + `, + }), + ); + + it( + 'handles TypeScript enums wrapped in parentheses', + testCase({ + input: ` + var ChangeDetectionStrategy; + ((function (ChangeDetectionStrategy) { + ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush"; + ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default"; + })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}))); + `, + expected: ` + var ChangeDetectionStrategy = /*#__PURE__*/ (function (ChangeDetectionStrategy) { + ChangeDetectionStrategy[(ChangeDetectionStrategy["OnPush"] = 0)] = "OnPush"; + ChangeDetectionStrategy[(ChangeDetectionStrategy["Default"] = 1)] = "Default"; + return ChangeDetectionStrategy; + })(ChangeDetectionStrategy || {}); + `, + }), + ); + + it( + 'wraps Crockford-style TypeScript enum IIFE without leaving dangling parentheses', + testCase({ + input: ` + var HDirection; + (function (HDirection) { + HDirection[HDirection['Backwards'] = -1] = 'Backwards'; + HDirection[HDirection['Forwards'] = 1] = 'Forwards'; + }(HDirection || (HDirection = {}))); + const nextStatement = true; + `, + expected: ` + var HDirection = /*#__PURE__*/ (function (HDirection) { + HDirection[(HDirection['Backwards'] = -1)] = 'Backwards'; + HDirection[(HDirection['Forwards'] = 1)] = 'Forwards'; + return HDirection; + }(HDirection || {})); + + const nextStatement = true; + `, + }), + ); + + it( + 'wraps TypeScript enum IIFE with multiple nested parentheses', + testCase({ + input: ` + var Foo; + (((function (Foo) { + Foo[Foo['A'] = 0] = 'A'; + }(Foo || (Foo = {}))))); + `, + expected: ` + var Foo = /*#__PURE__*/ (function (Foo) { + Foo[(Foo['A'] = 0)] = 'A'; + return Foo; + }(Foo || {})); + `, + }), + ); + + it( + 'wraps Crockford-style TypeScript enum IIFE with chained export assignments', + testCase({ + input: ` + var Foo; + (function (Foo) { + Foo[Foo['A'] = 0] = 'A'; + }(Foo || (Foo = exports.Foo = {}))); + `, + expected: ` + var Foo = /*#__PURE__*/ (function (Foo) { + Foo[(Foo['A'] = 0)] = 'A'; + return Foo; + }(Foo || (exports.Foo = {}))); + `, + }), + ); }); diff --git a/packages/angular/build/src/tools/babel/plugins/oxc-transform.ts b/packages/angular/build/src/tools/babel/plugins/oxc-transform.ts index 70989a8bc08d..569db927f45a 100644 --- a/packages/angular/build/src/tools/babel/plugins/oxc-transform.ts +++ b/packages/angular/build/src/tools/babel/plugins/oxc-transform.ts @@ -414,27 +414,30 @@ export function transform(filename: string, code: string, options: OxcTransformO continue; } - // 1. Remove only the trailing characters/semicolon of the expression statement + // 1. Remove leading/trailing characters/parentheses of the expression statement + s.remove(nextStatement.start, nextExpr.start); s.remove(nextExpr.end, nextStatement.end); - markEdited(nextExpr.end, nextStatement.end); + markEdited(nextStatement.start, nextStatement.end); // 2. Add return statement inside IIFE body s.appendRight(callee.body.end - 1, `; return ${paramName};`); // 3. Remove `Name = ` assignment in arguments if it's a simple identifier if (rightCallArgument.left.type === 'Identifier') { - s.overwrite( - arg.right.start, - arg.right.end, - code.substring(rightCallArgument.right.start, rightCallArgument.right.end), + let replacement = code.substring( + rightCallArgument.right.start, + rightCallArgument.right.end, ); + if (unwrapParentheses(rightCallArgument.right).type === 'AssignmentExpression') { + replacement = `(${replacement})`; + } + s.overwrite(arg.right.start, arg.right.end, replacement); markEdited(arg.right.start, arg.right.end); } // 4. Move IIFE to the var initializer s.move(nextExpr.start, nextExpr.end, decl.id.end); s.appendLeft(decl.id.end, ' = /*#__PURE__*/ '); - markEdited(nextExpr.start, nextExpr.end); } }