Skip to content

Commit

Permalink
Allow super.method() calls in constructor (#324)
Browse files Browse the repository at this point in the history
The old code assumed that `super` always followed by a `(` which is not
the case.

Also adds tests for invalid (at runtime) code with multiple `super()`
and `super.m()` / `super.x` / `super.x = 1` before `super()`.

Fixes #323
  • Loading branch information
arv authored and alangpierce committed Oct 28, 2018
1 parent 2cbe6fc commit 59159cb
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/util/getClassInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -220,6 +221,7 @@ function processConstructor(
tokens.nextToken();
}
constructorInsertPos = tokens.currentIndex();
foundSuperCall = true;
}
tokens.nextToken();
}
Expand Down
119 changes: 119 additions & 0 deletions test/typescript-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
`
Expand Down

0 comments on commit 59159cb

Please sign in to comment.