diff --git a/src/util/getClassInfo.ts b/src/util/getClassInfo.ts index d9fefcb6..67ee9712 100644 --- a/src/util/getClassInfo.ts +++ b/src/util/getClassInfo.ts @@ -209,8 +209,9 @@ function processConstructor( let constructorInsertPos = tokens.currentIndex(); // Advance through body looking for a super call. + let foundSuperCall = false; while (!tokens.matchesContextIdAndLabel(tt.braceR, constructorContextId)) { - if (tokens.matches1(tt._super)) { + if (!foundSuperCall && tokens.matches2(tt._super, tt.parenL)) { tokens.nextToken(); const superCallContextId = tokens.currentToken().contextId; if (superCallContextId == null) { @@ -220,6 +221,7 @@ function processConstructor( tokens.nextToken(); } constructorInsertPos = tokens.currentIndex(); + foundSuperCall = true; } tokens.nextToken(); } diff --git a/test/typescript-test.ts b/test/typescript-test.ts index f9b906ed..38416e09 100644 --- a/test/typescript-test.ts +++ b/test/typescript-test.ts @@ -104,6 +104,125 @@ describe("typescript transform", () => { ); }); + it("handles class field assignment after a constructor with multiple super calls", () => { + assertTypeScriptResult( + ` + class A extends B { + x = 1; + constructor(a) { + super(a); + super(b); + } + } + `, + `"use strict";const __init = Symbol(); + class A extends B { + [__init]() {this.x = 1} + constructor(a) { + super(a);this[__init]();; + super(b); + } + } + `, + ); + }); + + it("handles class field assignment after a constructor with super and super method call", () => { + assertTypeScriptResult( + ` + class A extends B { + x = 1; + constructor(a) { + super(a); + super.b(); + } + } + `, + `"use strict";const __init = Symbol(); + class A extends B { + [__init]() {this.x = 1} + constructor(a) { + super(a);this[__init]();; + super.b(); + } + } + `, + ); + }); + + it("handles class field assignment after a constructor with invalid super method before super call", () => { + assertTypeScriptResult( + ` + class A extends B { + x = 1; + constructor(a) { + super.b(); + super(a); + } + } + `, + `"use strict";const __init = Symbol(); + class A extends B { + [__init]() {this.x = 1} + constructor(a) { + super.b(); + super(a);this[__init]();; + } + } + `, + ); + }); + + it("handles class field assignment after a constructor with super prop", () => { + assertTypeScriptResult( + ` + class A extends B { + x = 1; + constructor(a) { + super(); + super.a; + super.b = 1; + } + } + `, + `"use strict";const __init = Symbol(); + class A extends B { + [__init]() {this.x = 1} + constructor(a) { + super();this[__init]();; + super.a; + super.b = 1; + } + } + `, + ); + }); + + it("handles class field assignment after a constructor with invalid super prop before super call", () => { + assertTypeScriptResult( + ` + class A extends B { + x = 1; + constructor(a) { + super.a; + super.b = 1; + super(); + } + } + `, + `"use strict";const __init = Symbol(); + class A extends B { + [__init]() {this.x = 1} + constructor(a) { + super.a; + super.b = 1; + super();this[__init]();; + } + } + `, + ); + }); + it("handles class field assignment with no constructor", () => { assertTypeScriptResult( `