Skip to content

Commit

Permalink
Port all babel-parser changes from 2018-10-01 to 2018-11-09 (#333)
Browse files Browse the repository at this point in the history
Notably, this adds support for TypeScript 3.0 syntax.

Details:
07862e727 Fix perf issue in typescript parser plugin (#8792)
🚫 Already implemented with a similar fix.

3c8740171 [decorators] [typescript] Parse type parameters (#8767)
✅ Straightforward port.

a5b5ed928 Typescript - Tuple elements can be optional (#8720)
✅ Straightforward port.

2575312d1 Fix parsing of slash after class expression (#8804)
✅ Already worked, added test.

850bc1d3d class private methods and properties: should not allow spaces between # and identifier (#8756)
🚫 Error checking only.

08454ece4 Typescript - Tuples can include rest elements (#8805)
✅ Straightforward port.

d2c75c2d3 fix: corrects handling of newline after async with paren-less arrow function (#8830)
✅ Straightforward port with new regression test.

ce1a6526e [email protected] (#8832)
🚫 Nothing to port.

8ee857e26 v7.1.3
🚫 Nothing to port.

929567523 Fixes #8865 (#8866)
🚫 Sucrase doesn't maintain curLine.

e4929e11f [flow] Explicit inexact objects with `...` (#8884)
✅ Relatively straightforward port with test. No error handling ported.

cd81b079e Allow function types in type params within arrow return types (#8954)
✅ Already worked, just implemented test.

f216a7b06 [flow] Add support for parsing `_` as implicit instantiation in call/new (#8883)
✅ Already worked, complexity in the babel code seemed to all be around error
handling.

24c4901ff Remove Babylon plugins for features already merged to the ECMAScript spec (#8448)
🚫 Sucrase doesn't have parser plugins.

e3b2c1aff fix: Do not allow TypeCastExpressions w/o parens (#8956)
🚫 Just extra error handling.

2194842d1 Typescript: Validate tuple type element positions (#8828)
🚫 Just error handling.

2fa198463 Fix await in function name and parameters (#7727)
🚫 Just error handling.

afe67a703 v7.1.5
🚫 Release only.

5d5cd8612 Fix several edge cases with context expression state (#8972)
✅ Added tests, but seems like everything was already working. The fixes were
all around context, and Sucrase got rid of context.

343f776ca Rename primitive types to reserved types (#8984)
🚫 Code doesn't exist in Sucrase.

4f206b241 [email protected] (#9001)
🚫 Tooling upgrade.
  • Loading branch information
alangpierce authored Nov 12, 2018
1 parent 3032f6b commit fadf8af
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/parser/plugins/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,13 @@ function flowParseObjectType(allowStatic: boolean, allowExact: boolean, allowPro
function flowParseObjectTypeProperty(): void {
if (match(tt.ellipsis)) {
expect(tt.ellipsis);
if (!eat(tt.comma)) {
eat(tt.semi);
}
// Explicit inexact object syntax.
if (match(tt.braceR)) {
return;
}
flowParseType();
} else {
flowParseObjectPropertyKey();
Expand Down
21 changes: 20 additions & 1 deletion src/parser/plugins/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
} from "../traverser/expression";
import {parseBindingList} from "../traverser/lval";
import {
baseParseMaybeDecoratorArguments,
parseBlockBody,
parseClass,
parseClassProperty,
Expand Down Expand Up @@ -418,12 +419,23 @@ function tsParseMappedType(): void {
function tsParseTupleType(): void {
tsParseBracketedList(
ParsingContext.TupleElementTypes,
tsParseType,
tsParseTupleElementType,
/* bracket */ true,
/* skipFirstToken */ false,
);
}

function tsParseTupleElementType(): void {
// parses `...TsType[]`
if (eat(tt.ellipsis)) {
tsParseType();
return;
}
// parses `TsType?`
tsParseType();
eat(tt.question);
}

function tsParseParenthesizedType(): void {
expect(tt.parenL);
tsParseType();
Expand Down Expand Up @@ -1402,3 +1414,10 @@ export function tsParseAssignableListItemTypes(): void {
tsTryParseTypeAnnotation();
popTypeContext(oldIsType);
}

export function tsParseMaybeDecoratorArguments(): void {
if (match(tt.lessThan)) {
tsParseTypeArguments();
}
baseParseMaybeDecoratorArguments();
}
7 changes: 6 additions & 1 deletion src/parser/traverser/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,12 @@ export function parseExprAtom(): boolean {
next();
parseFunction(functionStart, false, false);
return false;
} else if (canBeArrow && contextualKeyword === ContextualKeyword._async && match(tt.name)) {
} else if (
canBeArrow &&
!canInsertSemicolon() &&
contextualKeyword === ContextualKeyword._async &&
match(tt.name)
) {
parseIdentifier();
expect(tt.arrow);
// let foo = bar => {};
Expand Down
13 changes: 13 additions & 0 deletions src/parser/traverser/statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
tsParseExportDeclaration,
tsParseIdentifierStatement,
tsParseImportEqualsDeclaration,
tsParseMaybeDecoratorArguments,
tsStartParseFunctionParams,
tsTryParseClassMemberWithIsStatic,
tsTryParseExport,
Expand Down Expand Up @@ -243,6 +244,18 @@ function parseDecorator(): void {
parseIdentifier();
}
}
parseMaybeDecoratorArguments();
}

function parseMaybeDecoratorArguments(): void {
if (isTypeScriptEnabled) {
tsParseMaybeDecoratorArguments();
} else {
baseParseMaybeDecoratorArguments();
}
}

export function baseParseMaybeDecoratorArguments(): void {
if (eat(tt.parenL)) {
parseCallExpressionArguments(tt.parenR);
}
Expand Down
51 changes: 51 additions & 0 deletions test/flow-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,4 +328,55 @@ describe("transform flow", () => {
`,
);
});

it("allows explicit inexact types", () => {
assertFlowResult(
`
type T = {...};
type U = {x: number, ...};
type V = {x: number, ...V, ...U};
`,
`"use strict";
`,
);
});

it("allows function types as type parameters", () => {
assertFlowResult(
`
type T = Array<(string) => number>
`,
`"use strict";
`,
);
});

it("allows underscore type arguments in invocations", () => {
assertFlowResult(
`
test<
_,
_,
number,
_,
_,
>();
new test<_>();
`,
`"use strict";
test
();
new test();
`,
);
});
});
74 changes: 74 additions & 0 deletions test/sucrase-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,4 +629,78 @@ describe("sucrase", () => {
{transforms: ["imports", "typescript"]},
);
});

it("allows a class expression followed by a division operator", () => {
assertResult(
`
x = class {} / foo
`,
`
x = class {} / foo
`,
{transforms: []},
);
});

it("handles newline after async in paren-less arrow function", () => {
assertResult(
`
import async from 'foo';
async
x => x
`,
`"use strict";${IMPORT_DEFAULT_PREFIX}
var _foo = require('foo'); var _foo2 = _interopRequireDefault(_foo);
_foo2.default
x => x
`,
{transforms: ["imports"]},
);
});

it("handles various parser edge cases around regexes", () => {
assertResult(
`
for (const {a} of /b/) {}
for (let {a} of /b/) {}
for (var {a} of /b/) {}
function *f() { yield
{}/1/g
}
function* bar() { yield class {} }
<>
<Select prop={{ function: 'test' }} />
<Select prop={{ class: 'test' }} />
<Select prop={{ delete: 'test' }} />
<Select prop={{ enum: 'test' }} />
</>
`,
`const _jsxFileName = "";
for (const {a} of /b/) {}
for (let {a} of /b/) {}
for (var {a} of /b/) {}
function *f() { yield
{}/1/g
}
function* bar() { yield class {} }
React.createElement(React.Fragment, null
, React.createElement(Select, { prop: { function: 'test' }, __self: this, __source: {fileName: _jsxFileName, lineNumber: 15}} )
, React.createElement(Select, { prop: { class: 'test' }, __self: this, __source: {fileName: _jsxFileName, lineNumber: 16}} )
, React.createElement(Select, { prop: { delete: 'test' }, __self: this, __source: {fileName: _jsxFileName, lineNumber: 17}} )
, React.createElement(Select, { prop: { enum: 'test' }, __self: this, __source: {fileName: _jsxFileName, lineNumber: 18}} )
)
`,
{transforms: ["jsx"]},
);
});
});
35 changes: 35 additions & 0 deletions test/typescript-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1203,4 +1203,39 @@ describe("typescript transform", () => {
`,
);
});

it("parses type arguments on decorators", () => {
assertTypeScriptResult(
`
@decorator<string>()
class Test {}
`,
`"use strict";
@decorator()
class Test {}
`,
);
});

it("properly parses tuple types with optional values", () => {
assertTypeScriptResult(
`
let x: [string, number?, (string | number)?];
`,
`"use strict";
let x;
`,
);
});

it("allows a rest element on a tuple type", () => {
assertTypeScriptResult(
`
let x: [string, ...number[]];
`,
`"use strict";
let x;
`,
);
});
});

0 comments on commit fadf8af

Please sign in to comment.