Skip to content

Commit

Permalink
Fix crash on class fields that don't end in a semicolon (#271)
Browse files Browse the repository at this point in the history
Fixes #235

The previous code always ate the next token after a class field, which was a
semicolon in all test cases so far. However, if the class field didn't end in a
semicolon, it would eat the first token of the next class body member, which
would confuse all downstream code and lead to errors.

This means we end up leaving semicolons around in class bodies where class
fields were, but this shouldn't cause problems, and it seems best to keep the
transforms simple.
  • Loading branch information
alangpierce authored Jun 25, 2018
1 parent 6c3e80f commit 94e6a81
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 25 deletions.
1 change: 0 additions & 1 deletion src/util/getClassInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export default function getClassInfo(
classInitializers.push(`this${nameCode} =${expressionCode}`);
}
}
tokens.nextToken();
fieldRanges.push({start: statementStartIndex, end: tokens.currentIndex()});
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/flow-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ describe("transform flow", () => {
`,
`"use strict";
class C {
;
;
}
`,
);
Expand Down
56 changes: 51 additions & 5 deletions test/sucrase-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ describe("sucrase", () => {
`,
`"use strict";
class A {
;
} A.x = 3;
`,
{transforms: ["jsx", "imports", "typescript"]},
Expand All @@ -300,7 +300,7 @@ describe("sucrase", () => {
`,
`"use strict"; var _class;
const A = (_class = class {
;
}, _class.x = 3, _class)
`,
{transforms: ["jsx", "imports", "typescript"]},
Expand All @@ -316,7 +316,7 @@ describe("sucrase", () => {
`,
`"use strict";${ESMODULE_PREFIX}
class C {
;
} C.x = 3; exports.default = C;
`,
{transforms: ["jsx", "imports", "typescript"]},
Expand All @@ -337,8 +337,8 @@ describe("sucrase", () => {
var _A = require('A'); var _A2 = _interopRequireDefault(_A);
var _B = require('B'); var _B2 = _interopRequireDefault(_B);
class C {constructor() { this.a = _A2.default; }
;
;
} C.b = _B2.default;
`,
{transforms: ["jsx", "imports", "typescript"]},
Expand Down Expand Up @@ -505,4 +505,50 @@ describe("sucrase", () => {
{transforms: ["jsx", "imports", "typescript"]},
);
});

it("handles a static class field without a semicolon", () => {
assertResult(
`
class A {
static b = {}
c () {
const d = 1;
}
}
`,
`"use strict";
class A {
c () {
const d = 1;
}
} A.b = {};
`,
{transforms: ["imports"]},
);
});

it("handles a class with class field bound methods", () => {
assertResult(
`
export class Observer {
update = (v: any) => {}
complete = () => {}
error = (err: any) => {}
}
export default function() {}
`,
`"use strict";${ESMODULE_PREFIX}
class Observer {constructor() { this.update = (v) => {};this.complete = () => {};this.error = (err) => {}; }
} exports.Observer = Observer;
exports. default = function() {}
`,
{transforms: ["imports", "typescript"]},
);
});
});
6 changes: 3 additions & 3 deletions test/types-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ describe("type transforms", () => {
`,
`"use strict";
class A {constructor() { this.x = 2;this.y = {}; }
;
;
}
`,
);
Expand All @@ -135,7 +135,7 @@ describe("type transforms", () => {
`,
`"use strict";
class A {
;
}
`,
);
Expand Down
28 changes: 14 additions & 14 deletions test/typescript-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {
;
c() {
return "hi";
}
Expand All @@ -74,7 +74,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {
;
constructor() {;this.x = 1;
this.y = 2;
}
Expand All @@ -95,7 +95,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A extends B {
;
constructor(a) {
super(a);this.x = 1;;
}
Expand All @@ -113,7 +113,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {constructor() { this.x = 1; }
;
}
`,
);
Expand All @@ -128,7 +128,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A extends B {constructor(...args) { super(...args); this.x = 1; }
;
}
`,
);
Expand All @@ -143,7 +143,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A extends B {constructor(...args2) { super(...args2); this.args = 1; }
;
}
`,
);
Expand Down Expand Up @@ -307,8 +307,8 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {constructor() { this.f = function() {}; }
;
;
}
`,
);
Expand Down Expand Up @@ -362,9 +362,9 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {constructor() { this[a + b] = 3;this[0] = 1;this["Hello, world"] = 2; }
;
;
;
}
`,
);
Expand Down Expand Up @@ -698,7 +698,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {
;
constructor() {;this.x = 1;
}
}
Expand Down Expand Up @@ -834,7 +834,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {
;
getFoo() {
return foo;
}
Expand Down Expand Up @@ -968,7 +968,7 @@ describe("typescript transform", () => {
`,
`"use strict";
class A {constructor() { this.n = 3; }
;
}
`,
);
Expand Down

0 comments on commit 94e6a81

Please sign in to comment.