Skip to content

Commit

Permalink
Port all babel-parser changes from 2018-11-13 to 2019-01-24 (#439)
Browse files Browse the repository at this point in the history
Progress toward #437

Notes about each change:
4e1d6e7ff v7.1.6
🚫 Release only.

a2afb974b Fix parsing typescript function types with destructuring (#9035)
🚫 Already fixed with #278.

445b14148 Better error for disallowed trailing commas/parameters after rest elements (#9046)
🚫 Just error reporting.

e7f0c065c Bump some deps (#9056)
🚫 Nothing to do.

4f16a12c0 Fix bug with parsing TS generic async arrow function (#9055)
🚫 Sucrase seems unaffected by bug.

d2971a195 Fix compatibility between typescript and jsx plugins in interface declarations (#9058)
🚫 Sucrase seems unaffected by bug.

856edbf95 [flow] Allow type casts in array patterns inside arrow parameters (#9069)
🚫 Bug caused by error reporting, doesn't affect Sucrase.

61f2aed5b Disallow await inside arrow functions (#9074)
🚫 Error handling out of scope for Sucrase.

07eaa3c63 Ignore empty fixture directories and fix fixtures in the parser (#9113)
🚫 Test-only.

393283053 Parse non-octals with leading zeros in non strict mode correctly (#9114)
🚫 Sucrase assumes strict mode, so this doesn't apply.

fa9df678a Move tests from babylon to babel-parser and enable one test that works now
🚫 Test-only.

fdc869ce1 Merge pull request #8289 from valtech-nyc/implement-smart-pipeline-in-parser
✅ Almost all logic was for error-reporting and complexity around node creation, but
   I did add # as a valid expression.

282129ea6 v7.2.0
🚫 Release only.

4ca35ef8b Fix running flow on travis and update flow (#9128)
🚫 Types only.

72471aff6 Handle flow comments with leading spaces (#9168)
🚫 Sucrase doesn't do anything special for flow comments.

c1499b13a v7.2.2
🚫 Release only.

5cb38995c Allow keywords to be used in type annotations (#9184)
✅ I also fixed this for TypeScript.

0bb720401 v7.2.3
🚫 Release only.

b5177ce29 babel-parser: typescript: add missing bigint keyword (#9230)
🚫 Test only.

60ffe1d10 parser, smart pipes: Add test for async–await
🚫 Test only.

c586d4e8c parser, smart pipes: Add support for yield in pipeline bodies
🚫 Only validation change, startsExpr was removed from Sucrase.

a58893d1e Ensure modifiers are included in TSParameterProperty ranges (#9276)
🚫 AST only.

e43777bb5 Fix location for typescript type assertions in AST (#9284)
🚫 AST only, wasn't a problem in Sucrase tokens.

03022d169 Throw error if TypeScript class has empty implements (#9292)
🚫 Error handling only.

46e3f6df1 @babel/parser: include leading character into range of generic ArrowFunctionExpression (#9295)
🚫 AST only.

2cc037675 @babel/parser(ts): Add parsing of type import (#9302)
🚫 Already done in #380.

9764718c3 Disallow trailing comma after rest (#9311)
🚫 Error handling only.

5889620a6 Disallow `new import(x)` and `import(x,)` (#9313)
🚫 Error handling only.

3e4b608a8 Parse class heritage as strict mode code (#9315)
🚫 Sucrase is always in strict mode.

694e3fd8c Merge declaration and init of props in parser's state (#9312)
🚫 Refactor that isn't relevant to Sucrase.

e8038863c Fix range on TypeScript this type predicate (#9339)
🚫 AST only.

34c9890f4 Fix range on TypeScript index signature parameters (#9335)
🚫 AST only.

aaec2cd51 Fix handling newline with TypeScript declare and abstract classes (#9328)
✅ Implemented newline checking in various places.

0a88230ec Disallow async functions as loop bodies (#9314)
🚫 Error handling only.

a2e6d8e96 Disallow usage of invalid keyword after export abstract statement in Typescript (#9336)
🚫 Error handling only.

96a734314 Merge pull request #9348 from danez/perf
🚫 Nothing stood out as being valuable to incorporate.

f6ee26c3d v7.3.0
🚫 Release only.

af88e63df fix new keyword broken by recent refactoring (#9377)
🚫 Not relevant in Sucrase.

f2af6c117 v7.3.1
🚫 Release only.

f77c450cd Bump prettier (#9373)
🚫 Tooling only.

65febdd13 Refactor import and export parsing (#9326)
🚫 Skipping refactor for now since it's not clear that I'll need it.

93e1b5e61 Merge pull request #9375 from danez/contextual-let
🚫 Not necessary for strict mode.

8bc9f9a05 fix: Allow toplevel await when option true and correctly mark await keyword as unexpected (#9371)
🚫 Error handling only.

42c5d3fc4 Correctly fail for invalid yield in for (#9398)
🚫 Error handling only.

46ba5940c Make yield a contextual keyword (#9400)
🚫 Not necessary for strict mode.

7dc157f9b Fix location/range on TypeScript ExportNamedDeclarations (#9406)
🚫 AST only.
  • Loading branch information
alangpierce committed Mar 31, 2019
1 parent 36b9d76 commit e5e9003
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/parser/plugins/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,10 @@ function flowParsePrimaryType(): void {
if (state.type === tt._typeof) {
flowParseTypeofType();
return;
} else if (state.type & TokenType.IS_KEYWORD) {
next();
state.tokens[state.tokens.length - 1].type = tt.name;
return;
}
}

Expand Down
25 changes: 19 additions & 6 deletions src/parser/plugins/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,11 @@ function tsParseNonArrayType(): void {
tsParseParenthesizedType();
return;
default:
if (state.type & TokenType.IS_KEYWORD) {
next();
state.tokens[state.tokens.length - 1].type = tt.name;
return;
}
break;
}

Expand Down Expand Up @@ -779,6 +784,9 @@ function tsParseExternalModuleReference(): void {

// Returns true if a statement matched.
function tsTryParseDeclare(): boolean {
if (isLineTerminator()) {
return false;
}
switch (state.type) {
case tt._function: {
const oldIsType = pushTypeContext(1);
Expand Down Expand Up @@ -872,7 +880,7 @@ function tsParseExpressionStatement(contextualKeyword: ContextualKeyword): boole
function tsParseDeclaration(contextualKeyword: ContextualKeyword, isBeforeToken: boolean): boolean {
switch (contextualKeyword) {
case ContextualKeyword._abstract:
if (isBeforeToken || match(tt._class)) {
if (tsCheckLineTerminatorAndMatch(tt._class, isBeforeToken)) {
if (isBeforeToken) next();
state.tokens[state.tokens.length - 1].type = tt._abstract;
parseClass(/* isStatement */ true, /* optionalId */ false);
Expand All @@ -881,7 +889,7 @@ function tsParseDeclaration(contextualKeyword: ContextualKeyword, isBeforeToken:
break;

case ContextualKeyword._enum:
if (isBeforeToken || match(tt.name)) {
if (tsCheckLineTerminatorAndMatch(tt.name, isBeforeToken)) {
if (isBeforeToken) next();
state.tokens[state.tokens.length - 1].type = tt._enum;
tsParseEnumDeclaration();
Expand All @@ -890,7 +898,7 @@ function tsParseDeclaration(contextualKeyword: ContextualKeyword, isBeforeToken:
break;

case ContextualKeyword._interface:
if (isBeforeToken || match(tt.name)) {
if (tsCheckLineTerminatorAndMatch(tt.name, isBeforeToken)) {
// `next` is true in "export" and "declare" contexts, so we want to remove that token
// as well.
const oldIsType = pushTypeContext(1);
Expand All @@ -908,16 +916,17 @@ function tsParseDeclaration(contextualKeyword: ContextualKeyword, isBeforeToken:
tsParseAmbientExternalModuleDeclaration();
popTypeContext(oldIsType);
return true;
} else if (match(tt.name)) {
} else if (tsCheckLineTerminatorAndMatch(tt.name, isBeforeToken)) {
const oldIsType = pushTypeContext(isBeforeToken ? 2 : 1);
if (isBeforeToken) next();
tsParseModuleOrNamespaceDeclaration();
popTypeContext(oldIsType);
return true;
}
break;

case ContextualKeyword._namespace:
if (isBeforeToken || match(tt.name)) {
if (tsCheckLineTerminatorAndMatch(tt.name, isBeforeToken)) {
const oldIsType = pushTypeContext(1);
if (isBeforeToken) next();
tsParseModuleOrNamespaceDeclaration();
Expand All @@ -927,7 +936,7 @@ function tsParseDeclaration(contextualKeyword: ContextualKeyword, isBeforeToken:
break;

case ContextualKeyword._type:
if (isBeforeToken || match(tt.name)) {
if (tsCheckLineTerminatorAndMatch(tt.name, isBeforeToken)) {
const oldIsType = pushTypeContext(1);
if (isBeforeToken) next();
tsParseTypeAliasDeclaration();
Expand All @@ -942,6 +951,10 @@ function tsParseDeclaration(contextualKeyword: ContextualKeyword, isBeforeToken:
return false;
}

function tsCheckLineTerminatorAndMatch(tokenType: TokenType, isBeforeToken: boolean): boolean {
return !isLineTerminator() && (isBeforeToken || match(tokenType));
}

// Returns true if there was a generic async arrow function.
function tsTryParseGenericAsyncArrowFunction(): boolean {
const snapshot = state.snapshot();
Expand Down
6 changes: 6 additions & 0 deletions src/parser/traverser/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,12 @@ export function parseExprAtom(): boolean {
return false;
}

case tt.hash: {
// Smart pipeline topic reference.
next();
return false;
}

default:
unexpected();
return false;
Expand Down
24 changes: 24 additions & 0 deletions test/sucrase-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -773,4 +773,28 @@ describe("sucrase", () => {
{transforms: []},
);
});

it("handles smart pipeline syntax", () => {
assertResult(
`
value |> #
value |> (#)
value |> # + 1
value |> (() => # + 1)
function* f () {
return x |> (yield #);
}
`,
`
value |> #
value |> (#)
value |> # + 1
value |> (() => # + 1)
function* f () {
return x |> (yield #);
}
`,
{transforms: []},
);
});
});
11 changes: 11 additions & 0 deletions test/types-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,4 +506,15 @@ describe("type transforms", () => {
{expectedOutput: 5},
);
});

it("allows keywords as identifiers in a type context", () => {
assertTypeScriptAndFlowResult(
`
function foo(a: function) {}
`,
`"use strict";
function foo(a) {}
`,
);
});
});
57 changes: 57 additions & 0 deletions test/typescript-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1653,4 +1653,61 @@ describe("typescript transform", () => {
},
);
});

it("handles newlines before class declarations", () => {
assertTypeScriptResult(
`
abstract
class A {}
declare
class B {}
declare
const x: number, y: string;
declare
const { x, y }: { x: number, y: number };
declare
interface I {}
declare
let x;
declare
var x;
declare
var x: any;
module
Foo
{}
namespace
Foo
{}
type
Foo = string;
`,
`"use strict";
abstract
class A {}
declare
class B {}
declare
const x, y;
declare
const { x, y };
declare
declare
let x;
declare
var x;
declare
var x;
module
Foo
{}
namespace
Foo
{}
type
Foo = string;
`,
);
});
});

0 comments on commit e5e9003

Please sign in to comment.