From bf240d2c691ad808b9ec92174481e980b1037bb9 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 6 Jul 2016 14:08:21 -0700 Subject: [PATCH] Fix #9531: account for async as an contextual keyword when parsing export assignments --- src/compiler/parser.ts | 3 +- .../reference/exportDefaultAsyncFunction2.js | 56 +++++++++++++++++ .../exportDefaultAsyncFunction2.symbols | 53 ++++++++++++++++ .../exportDefaultAsyncFunction2.types | 61 +++++++++++++++++++ .../compiler/exportDefaultAsyncFunction2.ts | 28 +++++++++ 5 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/exportDefaultAsyncFunction2.js create mode 100644 tests/baselines/reference/exportDefaultAsyncFunction2.symbols create mode 100644 tests/baselines/reference/exportDefaultAsyncFunction2.types create mode 100644 tests/cases/compiler/exportDefaultAsyncFunction2.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d720cd0648f9d..dc2e114977f2c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1184,7 +1184,8 @@ namespace ts { function nextTokenIsClassOrFunctionOrAsync(): boolean { nextToken(); - return token === SyntaxKind.ClassKeyword || token === SyntaxKind.FunctionKeyword || token === SyntaxKind.AsyncKeyword; + return token === SyntaxKind.ClassKeyword || token === SyntaxKind.FunctionKeyword || + (token === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); } // True if positioned at the start of a list element diff --git a/tests/baselines/reference/exportDefaultAsyncFunction2.js b/tests/baselines/reference/exportDefaultAsyncFunction2.js new file mode 100644 index 0000000000000..ff242eec6a140 --- /dev/null +++ b/tests/baselines/reference/exportDefaultAsyncFunction2.js @@ -0,0 +1,56 @@ +//// [tests/cases/compiler/exportDefaultAsyncFunction2.ts] //// + +//// [asyncawait.ts] + +export function async(...args: any[]): any { } +export function await(...args: any[]): any { } + +//// [a.ts] +import { async, await } from 'asyncawait'; +export default async(() => await(Promise.resolve(1))); + +//// [b.ts] +export default async () => { return 0; }; + +//// [c.ts] +import { async, await } from 'asyncawait'; +export default async(); + +//// [d.ts] +import { async, await } from 'asyncawait'; + +export default async; + +//// [e.ts] +import { async, await } from 'asyncawait'; + +export default async + +export function foo() { } + +//// [asyncawait.js] +export function async(...args) { } +export function await(...args) { } +//// [a.js] +import { async, await } from 'asyncawait'; +export default async(() => await(Promise.resolve(1))); +//// [b.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments)).next()); + }); +}; +export default () => __awaiter(this, void 0, void 0, function* () { return 0; }); +//// [c.js] +import { async } from 'asyncawait'; +export default async(); +//// [d.js] +import { async } from 'asyncawait'; +export default async; +//// [e.js] +import { async } from 'asyncawait'; +export default async; +export function foo() { } diff --git a/tests/baselines/reference/exportDefaultAsyncFunction2.symbols b/tests/baselines/reference/exportDefaultAsyncFunction2.symbols new file mode 100644 index 0000000000000..013d0d7f697f7 --- /dev/null +++ b/tests/baselines/reference/exportDefaultAsyncFunction2.symbols @@ -0,0 +1,53 @@ +=== tests/cases/compiler/asyncawait.ts === + +export function async(...args: any[]): any { } +>async : Symbol(async, Decl(asyncawait.ts, 0, 0)) +>T : Symbol(T, Decl(asyncawait.ts, 1, 22)) +>args : Symbol(args, Decl(asyncawait.ts, 1, 25)) + +export function await(...args: any[]): any { } +>await : Symbol(await, Decl(asyncawait.ts, 1, 49)) +>args : Symbol(args, Decl(asyncawait.ts, 2, 22)) + +=== tests/cases/compiler/a.ts === +import { async, await } from 'asyncawait'; +>async : Symbol(async, Decl(a.ts, 0, 8)) +>await : Symbol(await, Decl(a.ts, 0, 15)) + +export default async(() => await(Promise.resolve(1))); +>async : Symbol(async, Decl(a.ts, 0, 8)) +>await : Symbol(await, Decl(a.ts, 0, 15)) +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) + +=== tests/cases/compiler/b.ts === +export default async () => { return 0; }; +No type information for this code. +No type information for this code.=== tests/cases/compiler/c.ts === +import { async, await } from 'asyncawait'; +>async : Symbol(async, Decl(c.ts, 0, 8)) +>await : Symbol(await, Decl(c.ts, 0, 15)) + +export default async(); +>async : Symbol(async, Decl(c.ts, 0, 8)) + +=== tests/cases/compiler/d.ts === +import { async, await } from 'asyncawait'; +>async : Symbol(async, Decl(d.ts, 0, 8)) +>await : Symbol(await, Decl(d.ts, 0, 15)) + +export default async; +>async : Symbol(async, Decl(d.ts, 0, 8)) + +=== tests/cases/compiler/e.ts === +import { async, await } from 'asyncawait'; +>async : Symbol(async, Decl(e.ts, 0, 8)) +>await : Symbol(await, Decl(e.ts, 0, 15)) + +export default async +>async : Symbol(async, Decl(e.ts, 0, 8)) + +export function foo() { } +>foo : Symbol(foo, Decl(e.ts, 2, 20)) + diff --git a/tests/baselines/reference/exportDefaultAsyncFunction2.types b/tests/baselines/reference/exportDefaultAsyncFunction2.types new file mode 100644 index 0000000000000..ae66620159df7 --- /dev/null +++ b/tests/baselines/reference/exportDefaultAsyncFunction2.types @@ -0,0 +1,61 @@ +=== tests/cases/compiler/asyncawait.ts === + +export function async(...args: any[]): any { } +>async : (...args: any[]) => any +>T : T +>args : any[] + +export function await(...args: any[]): any { } +>await : (...args: any[]) => any +>args : any[] + +=== tests/cases/compiler/a.ts === +import { async, await } from 'asyncawait'; +>async : (...args: any[]) => any +>await : (...args: any[]) => any + +export default async(() => await(Promise.resolve(1))); +>async(() => await(Promise.resolve(1))) : any +>async : (...args: any[]) => any +>() => await(Promise.resolve(1)) : () => any +>await(Promise.resolve(1)) : any +>await : (...args: any[]) => any +>Promise.resolve(1) : Promise +>Promise.resolve : { (value: T | PromiseLike): Promise; (): Promise; } +>Promise : PromiseConstructor +>resolve : { (value: T | PromiseLike): Promise; (): Promise; } +>1 : number + +=== tests/cases/compiler/b.ts === +export default async () => { return 0; }; +>async () => { return 0; } : () => Promise +>0 : number + +=== tests/cases/compiler/c.ts === +import { async, await } from 'asyncawait'; +>async : (...args: any[]) => any +>await : (...args: any[]) => any + +export default async(); +>async() : any +>async : (...args: any[]) => any + +=== tests/cases/compiler/d.ts === +import { async, await } from 'asyncawait'; +>async : (...args: any[]) => any +>await : (...args: any[]) => any + +export default async; +>async : (...args: any[]) => any + +=== tests/cases/compiler/e.ts === +import { async, await } from 'asyncawait'; +>async : (...args: any[]) => any +>await : (...args: any[]) => any + +export default async +>async : (...args: any[]) => any + +export function foo() { } +>foo : () => void + diff --git a/tests/cases/compiler/exportDefaultAsyncFunction2.ts b/tests/cases/compiler/exportDefaultAsyncFunction2.ts new file mode 100644 index 0000000000000..2d2ee4ef345e7 --- /dev/null +++ b/tests/cases/compiler/exportDefaultAsyncFunction2.ts @@ -0,0 +1,28 @@ +// @target: es6 + +// @filename: asyncawait.ts +export function async(...args: any[]): any { } +export function await(...args: any[]): any { } + +// @filename: a.ts +import { async, await } from 'asyncawait'; +export default async(() => await(Promise.resolve(1))); + +// @filename: b.ts +export default async () => { return 0; }; + +// @filename: c.ts +import { async, await } from 'asyncawait'; +export default async(); + +// @filename: d.ts +import { async, await } from 'asyncawait'; + +export default async; + +// @filename: e.ts +import { async, await } from 'asyncawait'; + +export default async + +export function foo() { } \ No newline at end of file