diff --git a/packages/devextreme/build/vite-plugin-devextreme.test.ts b/packages/devextreme/build/vite-plugin-devextreme.test.ts index 620c257266e2..d827da0c7ec2 100644 --- a/packages/devextreme/build/vite-plugin-devextreme.test.ts +++ b/packages/devextreme/build/vite-plugin-devextreme.test.ts @@ -19,6 +19,10 @@ function transform(code: string, plugin: unknown): string { return result!.code!; } +function normalize(code: string): string { + return code.replace(/\s+/g, ' ').trim(); +} + describe('moveFieldInitializersToConstructor', () => { test('inserts field initializer after super() in derived class', () => { const input = ` @@ -128,6 +132,31 @@ describe('moveFieldInitializersToConstructor', () => { const out = transform(input, moveFieldInitializersToConstructor); expect(out).toMatch(/constructor\(\)\s*\{\s*this\.foo\s*=\s*42;\s*const\s+x\s*=\s*1;\s*this\.x\s*=\s*x/); }); + + test('inserts right after super() when a non-matching statement precedes param-property assignment', () => { + const input = ` + class Derived extends Base { + cached = 'init'; + constructor(x) { + super(); + this.doSetup(); + this.x = x; + } + } + `; + const expected = ` + class Derived extends Base { + constructor(x) { + super(); + this.cached = 'init'; + this.doSetup(); + this.x = x; + } + } + `; + const out = transform(input, moveFieldInitializersToConstructor); + expect(normalize(out)).toBe(normalize(expected)); + }); }); describe('removeUninitializedClassFields', () => { diff --git a/packages/devextreme/build/vite-plugin-devextreme.ts b/packages/devextreme/build/vite-plugin-devextreme.ts index 81a29f54b212..62dffb863e23 100644 --- a/packages/devextreme/build/vite-plugin-devextreme.ts +++ b/packages/devextreme/build/vite-plugin-devextreme.ts @@ -89,12 +89,15 @@ export function moveFieldInitializersToConstructor(): unknown { const ctorBody = ctor.body!.body as Stmt[]; - let insertAt = 0; - for (let i = 0; i < ctorBody.length; i += 1) { - const stmt = ctorBody[i]; - const isSuperCall = stmt.type === 'ExpressionStatement' + const superCallIdx = ctorBody.findIndex( + (stmt) => stmt.type === 'ExpressionStatement' && stmt.expression?.type === 'CallExpression' - && stmt.expression.callee?.type === 'Super'; + && stmt.expression.callee?.type === 'Super', + ); + + let insertAt = superCallIdx !== -1 ? superCallIdx + 1 : 0; + while (insertAt < ctorBody.length) { + const stmt = ctorBody[insertAt]; const isParamPropertyAssignment = stmt.type === 'ExpressionStatement' && stmt.expression?.type === 'AssignmentExpression' && stmt.expression.operator === '=' @@ -104,7 +107,8 @@ export function moveFieldInitializersToConstructor(): unknown { && stmt.expression.left.property?.name === stmt.expression.right.name && paramNames.has(stmt.expression.right.name!); - if (isSuperCall || isParamPropertyAssignment) insertAt = i + 1; + if (!isParamPropertyAssignment) break; + insertAt += 1; } ctorBody.splice(insertAt, 0, ...(assignments as Stmt[]));